Reputation: 21
I am writing unitests for a legacy application without any automated tests. While writing I realized that without refactoring the unittests get pretty large. So without Refactoring i need many Function to keep my tests readable. Is it okay to use "Arrange" or "Setup" Methods in your Tests to keep them readable? Or is my test to complicated. Here is some Pseudocode.
[TestMethod]
public TestFoo()
{
Obj1 obj1;
Obj2 obj2;
...
//arrange
SetupObjects(obj1, obj2);
//act
Foo.foo( ojb1, obj2);
//assert
AssertObjectStates( obj1, obj2);
}
SetupObjects(Obj1 obj1, Obj2 obj2)
{
CreateAndDoSomethingWithObj1(obj1);
MockSomethingInObj2(obj2);
}
...
Upvotes: 0
Views: 39
Reputation: 5939
It is very common to have helper functions as part of test code. Some situations in which it can be beneficial are:
Test code tends to be repetitive, so helper functions can help to reduce code duplication. This simplifies the creation and maintenance of test suites with larger number of tests. (Note that there are also other mechanisms to reduce code duplication: Typically the frameworks offer some kind of setup and teardown interface which are implicitly called before and after each test, respectively. However, these often lead to a phenomenon that Meszaros calls "mystery guest": Something magic seems to happen outside of the test code. Instead of these implicitly called setup and teardown methods, explicitly called and clearly named helper functions are a good mechanism to get the best of both worlds, namely to avoid duplication in test setups and still make it easy to fully understand each test.)
Encapsulate test code that uses implementation details or non-public interfaces: Unit-testing is the test level closest to the implementation, and if your intent is also to find implementation specific bugs, some tests will be implementation specific. There are also other situations where tests are built upon glass box (aka white box) knowledge, like, when you are looking at code coverage (e.g. MC/DC coverage). This, however, means when designing and implementing your tests, you have to find ways to keep test code maintenance effort low. By encapsulating parts of the test code where implementation details are used, you can end up with tests that also find implementation leven bugs, but still keep maintenance effort on an acceptable level.
Now, looking at your code. It is certainly only example code, therefore the following may be clear for you, even it is not apparent from the code: The way helper functions are used there is not fortunate. The function SetupObjects
is not descriptive. And, it sets up both objects individually although for a reader of the test code it appears as if SetupObjects
would do something common to both objects.
Upvotes: 1