c# - understanding some unit testing practices -
i newbie unit testing - have done basic assert tests using mere testmethods(my last module, created 50 of those).
i reading book on unit testing, , 1 of many examples in book has me creating new class each single test. below 1 of example objects created 1 test case. question is ever necessary this? or when should 1 apply approach , when not necessary?
public class and_saving_an_invalid_item_type : when_working_with_the_item_type_repository { private exception _result; protected override void establish_context() { base.establish_context(); _session.setup(s => s.save(null)).throws(new argumentnullexception()); } protected override void because_of() { try { _itemtyperepository.save(null); } catch (exception exception) { _result = exception; } } [test] public void then_an_argument_null_exception_should_be_raised() { _result.shouldbeinstanceoftype(typeof(argumentnullexception)); } }
do need create new class each individual test? no, not. don't know why book saying that, or if doing illustrate examples.
to answer question, i'd recommend using class each group of tests... it's bit more complex that, because how define "group" varying , dependant on you're doing @ time.
in experience, set of tests logically structured document, can contain 1 or more set of tests, grouped (and nested) common aspect. natural grouping testing object-oriented code group class, , method.
here's example
- tests class 1
- tests method 1
- primary behaviour of method 1
- alternate behaviour of method 1
- tests method 2
- primary behaviour of method 2
- alternate behaviour of method 2
- tests method 1
unfortunately, in c# or java (or similar languages), you've got 2 levels of structure work (as opposed 3 or 4 want), , have hack things fit.
the common way done use class group sets of tests, , don't group @ method level, this:
class testsforclass1 { void test_method1_primary() void test_method1_alternate() void test_method2_primary() void test_method2_alternate() } if both method 1 , method 2 have identical setup/teardown, fine, don't, leading breakdown:
class testsforclass1_method1 { void test_primary() void test_alternate() } class testsforclass1_method2 { void test_primary() void test_alternate() } if have more complex requirements (let's have 10 tests method_1, first 5 have setup requirement x, next 5 have different setup requirements), people end making more , more class names this:
class testsforclass1_method1_withrequirementx { ... } class testsforclass1_method1_withrequirementy { ... } this sucks, hey - square peg, round hole, etc.
personally, i'm fan of using lambda-functions inside methods give third level of grouping. nspec shows 1 way can done... have in-house test framework different, reads bit this:
class testsforclass1 { void testsformethod1() { it.should("perform it's primary function", () => { // .... }); it.should("perform it's alternate function", () => { // .... }); } } this has downsides (if first statement fails, others don't run), consider tradeoff worth it.)
-- question read: "is ever necessary create object each single test want carry out?". answer (mostly) yes, per explanation.
generally, unit tests involve interaction of 2 parts
- the object under test. instance of class or function you've written
- the environment. whatever parameters you've passed function, , whatever other dependencies object may have reference to.
in order unit tests reliable, both of these parts need "fresh" each test, ensure state of system sane , reliable.
if thing under test not refreshed each test, 1 function may alter object's internal state, , cause next test wrongly fail
if environment not refreshed each test, 1 function may alter environment (eg: set variable in external database or something), may cause next test wrongly fail.
there many situations not case - might example have pure mathematical function takes integers parameters , doesn't touch external state, , may not want bother re-creating object under test or test environment... generally, things in object-oriented system need refreshing, why "standard practice" so.
Comments
Post a Comment