I'm writing unit tests for my webapp. Many of my test cases share the same boilerplate. For example, the tests for removing an item from the cart and updating the quantity of an item in the cart both start with navigating to the products page, searching for a product, and adding it to the cart.
Should such duplicated code be factored out of the unit tests somehow? Should I write a function add_item_to_cart
? But, I have another test test_add_to_cart
, which basically only consists of this duplicated boilerplate of adding to the cart.
Are unit tests by nature not DRY because of the need for each test to be independent?
Unit tests are supposed to test just one thing. A test that starts with "navigating to the products page, searching for a product, and adding it to the cart" -- that's three different things right there -- doesn't sound like a unit test at all, but an integration test. I suspect you thus actually have two different tests to build here.
Your integration test, in Cucumber or something similar, should consist of a series of steps:
When I navigate to the products page
And I search for a product
And I add it to the cart
You can define each step once and use it multiple times, making it nice and DRY.
Your unit test, on the other hand, should stub out all the setup necessary and just test the one thing you are interested in:
before
stub(cart)
stub(product)
click on "X" for item in cart
it should...
expect(cart not to contain item)
expect(product count to be updated)
If this turns out to be really complicated and involve a lot of stubbing, it's an indicator that your code is not modular; the solution is to TDD and write the tests first, instead of adding them afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With