As the title suggests my question is whether or notunit-tests should be entirely self-contained or canone rely on the results yielded by previous tests?What I mean, in case that it isn't entirely clear,is that if ones initial test sufficiently assertsthat a certain module A works in a certain way can,or more appropriately, should one write subsequenttests with the assumption that the aforementionedmodule A is tested beforehand? This would imply thatthe order that the unit-tests are executed matters.Or should each individual test be self-reliantto the point that if one needs to know whether amodule B works, which can only be validatedif module A works, should one then test module Awithin the same test as module B whichwould imply that the separate unit-tests can beexecuted in any order.To give a concrete example, consider the stack datatype, which we won't delve too deeply into, specifically two fundamental properties we'd need to be able to reason about the datatype in any meaningful sense. Namely, isEmpty(stack) and Empty(). Now, if one wishes to test the validity of isEmpty which takes a stack and returns a True or False depending on whether or not the stack received as an argument is empty or not one would first need to create an empty stack using Empty().Then we consider the scenario of doing the following: isEmpty(Empty()) and checking what kind of result we get. Either we get a True statement, so Empty() could have returned a non empty stack and isEmpty might view that as an empty stack which would be wrong. Or we get False, and we still don't know how the two actually interplay, nor how either works on their own (assuming we can't view the source). (There is a third option, we receive something that's neither True nor False, but that is beyond the scope of this discussion, this is solely a remark).Finally, to tie this back to my question, if we create a test where we can be reasonably certain that isEmpty works in a satisfying manner can then all tests executed after it trust that it does indeed work? Or should they all try and incorporate this ambiguity into their own test logic (for instance, including an else statement to if neither True nor False was returned)
Should unit-tests be entirely self-contained?
unit testing;debugging;dry;structured programming
Each unit test should be testing one thing, so yes, they should assume that all other parts of the system is working. The way to do this reliably is to mock any other code which should not be tested at the same time.For example, consider this pseudo-code:house_json(id):    name = get_house_name(id)    return json.format({'id': id, 'name': name})This depends on the functionality of two other functions: get_house_name and json.format. To unit test this you'll have to mock both of them. First the normal case, testing that with a valid house ID we end up calling json.format with the expected parameters:test_house_json_format():    get_house_name = mock()    json.format = mock()    get_house_name.return_for(5) = 'foo'    house_json(5)    assert_called_once_with(json.format, {'id': 5, 'name': 'foo'})Then to test that if we send an invalid house ID, the formatter should throw an exception:test_house_json_with_invalid_house_id():    get_house_name = mock()    json.format = mock()    get_house_name.return(x) = lambda: raise InvalidHouseError(x)    assert_raises(house_json, 5, InvalidHouseError)    assert_not_called(json.format)Making expectations about the code explicit in your test code means it will be easy for others to understand its expected behaviour, and to change it when requirements change. For example, if the function should handle thrown errors and return an error code in JSON format instead, you'd change that in this test:test_house_json_with_invalid_house_id():    get_house_name, json.format = mock()    get_house_name.return(x) = lambda: raise InvalidHouseError(x)    house_json(5)    assert_called_once_with(json.format, {'invalid_house_error': 5})Then you'd run the test to verify that it fails, fix get_house_name to make it pass again, and refactor to make it the simplest possible code which passes (red-green-refactoring).Once you've tested all the parts, you should add integration and acceptance tests without mocking to ensure that they all work together.