I try to make a suite of tests with phpunit
with dependence between several classes. I have 3 classes, A, B and C, with tests in each classes. A has 5 tests, B 3 tests et C 3 tests.
B has dependant tests on A, C has dependant tests on A and the A final tests depends on B and C tests.
class A extends TestCase {
public function test1(){}
// @depends test1
public function test2(){}
// @depends test2
public function test3(){}
// @depends test3
public function test4(){}
// @depends test3
// @depends B::test3
// @depends C::test3
public function test5(){}
}
class B extends TestCase {
// @depends A::test1
public function test1(){}
// @depends B::test1
public function test2(){}
// @depends B::test2
// @depends A::test4
public function test3(){}
}
class C extends TestCase {
// @depends A::test1
public function test1(){}
// @depends C::test1
public function test2(){}
// @depends C::test2
// @depends A::test4
public function test3(){}
}
My problem in this case is that A::test5, B::test3 and C::test3 are skipped.
what you have is a very poor design for your tests.
You should be able to run all your tests independently of each other.
If you need certain data to be setup beforehand, then do it in a setUp()
method, or in the test method itself.
As has already been pointed out, if you have external dependencies, mock them.
If you have a set of tests that all require the same, or similar data, then its perfectly acceptable to put that setup code in a base class, and then extend that with your tests. Something like this.
class AppTestCase extends TestCase
{
public function setUp()
{
// this will be run before every test class that extends this class. So make your test user/product here.
// you can invoke all your mocking in here to if thats easier,
// just make sure the resulting mock objects are all in visible
// properties to be accessed elsewhere
}
public function tearDown()
{
// if youre functional testing, remove test data in here. This will fire after each test has finished in any class that extends this one.
}
}
class A extends AppTestCase
{
public function setUp()
{
parent::setUp();
// do other, class specific setup stuff here.
}
public function test1()
{
// your test data will be setup for you by the time you get here.
// if you only have 1 test and it needs adapted base data, do it here,
// if you have lots of tests in here, override and extend the `parent::setUp()` method.
}
}
then repeat that pattern for all your tests.