简体   繁体   中英

Persist DB between tests in Codeception

I'm testing a CRUD application written in L5 using Codeception acceptance tests. I was wondering how you guys go about this.

I originally thought I'd be able to use a CEST and use the @depends property to specify the order but it seems the auto DB cleanup is ran after each test, so after my insert the next test can't find that record in the DB.

Is there a way I can do this without specifically making up a DB dump specifically for testing?

I was hoping to be able to have the following tests in this order:

  • Create Item
  • Read Item
  • Update item
  • Delete Item

and check the DB at each stage to make sure it was successful.

Any help would be greatly appreciated.

Cheers, Daryll

The default behaviour specified here is definitely what you want . You want the tests to be able to be performed in isolation. If you want to retest an area again, because it is broken, you don't have to go back and run your previous tests again to get it in the correct state to run the tests again.

A single broken test will give you a better idea of where the breakage is, rather than having multiple broken tests because a test that all your other tests depend on was broken , which is what the approach you are describing lends itself to.

If you think about it, say you are doing test driven development. You write a breaking test with the correct data that Creates a record. The other tests are to read, update, read again, delete the record, update a different record, create another new record, and read again. The delete fails, and the create and read tests fail because you reinsert the same index. The tests wont tell you that however, you just get 4 broken tests, and you will have to check all of your tests that are broken, and which one caused the other tests break, if that is indeed the case. You wont know.

If you do what the default behaviour tells you to do, you will have just the one broken test, and you fix the issue. Dead easy. You just add to the database as test cases arise to accommodate for them.

If you want to check what's in the database, you can do that by querying twice in the same test. Perform your update query then run your select query on what you have just done, and do and equals as another assertion. You can trust that the database has ran your query if you set it up correctly and get no errors, but you know your application better. Maybe you have triggers running, for instance.

I believe you can stop the behaviour with this sort of thing in a config, but its not what you want!:

class_name: FunctionalTester
modules:
    enabled: [Filesystem, FunctionalHelper, Laravel4, Asserts]
    config:
        Laravel4:
            environment: 'testing'
            cleanup: false

I have an experience on a large scale application where at some point a decision was maid to check DB on every test. 2 Years later world of pain and useless, slow, unmanageable tests. So lessons learned from that: Do not test data in DB on unittest.

Purpose of unit tests is to test code you wrote!

When you test that proper data got to DB you test:

  1. DBAL Driver (Larvel).
  2. PHP DB Driver (whatever larvel uses).
  3. DB itself (whatever DB).

That creates unnecessary complexity of test:

  1. Every test environment should have all those components properly setup.
  2. You need to make sure that data is consistent between tests. So easiest way is to clean data after every test and each test should create its own data(very slow).
  3. And you repeat work done by DB creators, Driver creators and Larvel ...

As a result: Tests getting slower, management of test environment gets harder. That leads to the point when you stop writing tests...

So solution is to write your classes to use DI and Mock DBAL on tests. There libraries that can help with DB mocking. But at the very end you should just test your code. That it calls proper functions with proper data and properly reacts to data that comes from DB.

And if you want to make sure that your DBAL works properly run it's unittest.

As for project I worked on there is an effort to move all test out of DB to mocks and speed improvements are x 1000 for tests that got changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM