Is it possible to use PHPUnit @depends without calling tearDown and setUp between dependent cases?

For example, the action in test1 stores data outside *, which test2 then executes the statement, but tearDown deletes this data, thereby violating test2 . Deleting a cache cannot be deleted from tearDown , as other tests depend on it. This question asks if there is a way to skip setUp / tearDown between dependent cases while maintaining @depends functionality (which skips the second test if the first test fails instead of the second test)

 public function tearDown() { // delete cache } // verify the expected data was retrieved from an uncached source public function test1() { $sut = new SystemUnderTest(); $data = $sut->getDataAndCache(); $this->assertEquals('expected', $data); return $sut; } // verify the expected data was cached /** @depends test1 */ public function test2($sut) { $this->assertEquals('expected', $sut->getCache()); } 

* We will call these integration tests because they interact with an external system.

+6
source share
4 answers

In the setup method, you can check if the hasDependencies() test has it, and then skip the setup procedures:

 public function setUp() { if (!$this->hasDependencies()) { // do setup tasks } } 
+12
source

There are several options.

The first of these will be the allocation of these two tests into a separate test class. This way your tearDown in other classes will not interfere.

You can still get rid of the cache after the test. Well, testing cache removal can be one of the steps. But PHPUnit also offers two static methods that run before the test class runs, and after all the tests in the class have been run: setUpBeforeClass() and tearDownAfterClass() (see http://phpunit.de/manual/3.7/en /fixtures.html ).

On the other hand, the easiest way out is to combine the two test methods into an ONE function. You already have some problems with violating the principle of single responsibility, calling the function getData * AND * Cache, so there is no use in dividing the test into two functions.

+1
source

One of my ideas is to use a static field like is_depends , which will be set to true in test1 , and false in test2 and setUp and tearDown will check the is_depends value before running. For instance.

 private static is_depends; public function setUp() { if (self::$is_depends) return; // do setup that shouldn't be done between dependencies } public function tearDown() { if (self::$is_depends) return; // delete cache } // verify the expected data was retrieved from an uncached source public function test1() { $sut = new SystemUnderTest(); $data = $sut->getDataAndCache(); $this->assertEquals('expected', $data); self::$is_depends = true; return $sut; } // verify the expected data was cached /** @depends test1 */ public function test2($sut) { $this->assertEquals('expected', $sut->getCache()); self::$is_depends = false; } 

Is there a better way?

0
source

Another option is to complete most of the arrangement steps and actions in both tests. Then there would be no need to maintain an external state between test1 and test2. @depends will still call test2 if test1 failed. If the arrangement steps and actions were more complex, they could be extracted into a separate method and called by both tests.

Here's an example of an updated test2 method (using test1 from the original question):

 // verify the expected data was cached /** @depends test1 */ public function test2($sut) { $data = $sut->getDataAndCache(); $this->assertEquals('expected', $sut->getCache()); } 
0
source

Source: https://habr.com/ru/post/952443/


All Articles