Should E2E tests expected results be hard coded or calculated?

212 Views Asked by At

I'm an BE engineer with experience in BE unit testing too, but recently started working on FE end-to-end tests, using Playwright and Cucumber. Should the expected result of a scenario be a hard-coded example or should it be calculated as part of the test?

For simplification, let's say I'm trying to write a test for a discount on an e-commerce site, and I'm writing a test to verify the discount amount is correct. It takes the user's basket total as an input and performs a client-side calculation to apply a fixed 12% discount, and spits the result back to the user. Should I be calculating that 12% within the step definitions of the test? Or should I hard-code the expected result? Feature file would look something like this if I was hard-coding the expected result:

Scenario: Verify discount amount is correct
Given  the shopping basket total is 60.00
When  I click "Calculate Discount"
Then  the reduction should be 7.20

Or should the last line be changed to calculate it like Then the reduction should be as expected and the step definition file doing something like

@Then("the reduction should be as expected")
public void theReductionShouldBe() {
    double actual = getReductionDisplayedToUser();
    double expected = basketTotal * 0.12;
    assertEquals(expected, actual);
}

In reality the calculation for the tool I'm testing is more complicated than just working out 12% (there's several inputs instead of just one), so my issue with the latter is that I'm duplicating all the logic in my e2e testing repo. But there's an argument that if the logic should change, I don't need to touch my feature file, and can just update the logic in the calculation. I personally prefer the former as it's similar to the testing style of my BE unit tests, but not sure if that's the best practice with E2E tests.

Another colleague has suggested I implement randomness to the inputs (and that would only work with the calculated result), but it seems strange to me to theoretically have a test that sometimes fails and sometimes passes if there is a bug in the logic, making maintenance a bit more difficult such as checking the bug as been fixed after a failed test.

Scenario: Verify discount amount is correct
Given  the shopping basket total is a random amount between 0.00 and 1000.00
When  I click "Calculate Discount"
Then  the reduction should be as expected

As I said I'm a bit new to E2E testing, and I'm not sure if there's any standards or best practices with this. Any thoughts?

3

There are 3 best solutions below

0
Vinit More On BEST ANSWER

If you follow cucumber official scenario example document of 'Writing better Gherkin', they have written expected values in Then condition

Official Cucumber document for Writing better Gherkin

You can also follow Scenario Outline where you can test multiple conditions

Scenario Outline Example

    Scenario Outline: Verify discount amount is correct
    Given  the shopping basket total is <total>
    When  I click "Calculate Discount"
    Then  the reduction should be <expected>

 Examples:
    | total  | expected |
    | 60.00  |   7.20   |
    | -1     |   0      |

And then you can play within different examples

0
M.P. Korstanje On

I think your scenario is missing a step.

Scenario: Verify discount amount is applied
  Given the shopping basket total is €60
  And a 12% discount is applicable
  When I click "Calculate Discount"
  Then the reduction should be €7.20

With this missing step (of either verifying there is, or applying a 12% discount) it makes sense to test the discount as a currency value.

0
Vishal Aggarwal On

Use both. Use test Oracles.

What is Test Oracle? Test oracle basically gives you the expected results to compare with the actual results for a given set of test scenarios as an external source of truth. Independent of the application logic as well as with its tests.

It could be as simple as an excel file with expected values calculated inside the sheet standalone of the application logic which can be passed to a test.

The advantage of this approach is :

  • It separates the application logic from test verification logic.
  • It even further separates the expected values from a specific implementation of the test. So in case if the same test takes an altogether different form in future in terms of automation tool/framework/library - the expected values remains the same as it comes from the business domain not from the technology of the application or the automation tool.
  • In future if the application logic changes , it only needs to be updated and calculated once in that sheet/or document and will reflect everywhere in the dependent tests.