@Ben
Thanks for the info, I didn't know about Flyway. But basically I think that 
a test database creation script could be under version control, so that 
developers can check out earlier versions, recreate the corresponding 
version of the database, run tests and develop the app. I don't think I 
need to go much further for handling schema change. My biggest worry with a 
solution involving Dbunit dataset files would be the need of regenerating 
them as the database is evolving, it seems that it would still require me 
to maintain an up-to-date physical version of the test database.

No matter how I look at it, maintaining a test database seems unavoidable. 
As for handling schema change in production, I will need to maintain a set 
of DDL patches as well in any case.
I also expect every developer to have his own test database or schema and 
to be responsible for evolving it.

@Lukas
Yes I have seen your blog post about mocking records. Honestly I don't 
think it's the right direction because it's almost as much work as 
maintaining or populating a physical test database (you need to provide 
values for every field), you may need a lot of different dedicated data 
provider classes to fit your testing needs and at the end of the day, you 
still don't know whether your query would actually return the expected 
result in the correct form or not. 
As for integration tests, I really think it makes sense to indirectly test 
database interactions in a business application, a lot of problems can 
happen in the lower layers. I completely fail to understand why so many 
blog posters, book writers and pseudo-agile consultants keep arguing the 
opposite. Perhaps because in theory, we are all manipulating fully object 
oriented entities in memory, while persistence is ehhhm "taken care 
somewhere else (tm)".

This afternoon I tried simulating a PostgreSQL database using H2, here is 
an extract of a @Before method

Connection conn = 
DriverManager.getConnection("jdbc:h2:mem:test;DATABASE_TO_UPPER=false;MODE=PostgreSQL",
 
"user", "password");
RunScript.execute(conn, new FileReader("h2_version.sql"));

Settings settings = new Settings()
                .withRenderSchema(false);

sqlFactory = new Factory(conn, SQLDialect.H2, settings );
PlatformRecord platformRecord = sqlFactory.newRecord(Tables.T_PLATFORMS);
platformRecord.setCurrencyCode("CHF");
platformRecord.setPlatformName("TestPlatform");
platformRecord.setShopId("FAKE123");

platformRecord.store();
//insert a few more records here to have a minimal setup

After that, I was able to test some business logic stuff. It's not a proof 
that such tests would work against postgresql, nevertheless it allowed me 
to detect 2 bugs. And it took me only 5 minutes to make my Postgresql DDL 
script work with H2.
It might be able to switch from H2 to postgres by changing 2 or 3 lines in 
the Factory creation code, it can be interesting for everyday use because 
it has almost 0 dependency on your actual environment. However it probably 
won't work with less trivial database interactions. Perhaps I could create 
an H2 compatible test suite (95% of the app) and a PostgreSQL only test 
suite for the more advanced stuff using the same Jooq generated code.

Hard to make decision...
I am also curious to hear what other people are doing.


Le mercredi 8 mai 2013 14:24:50 UTC+2, Lukas Eder a écrit :
>
> Hi Stéphane,
>
> After an interesting request on this user group by Aaron Digulla:
> https://groups.google.com/d/msg/jooq-user/OQzuxbqk-w8/MbtmKAnZ2h4J
>
> I have implemented a mock database to suit his needs, which are the actual 
> mocking of the database (instead of integration testing). I then wrote an 
> article which was reblogged to DZone and lead to heated, yet interesting 
> discussions:
>
> http://blog.jooq.org/2013/02/20/easy-mocking-of-your-database
> http://architects.dzone.com/articles/easy-mocking-your-database-0
>
> While I don't think that there is a definitive answer to your question, 
> short of "it depends", I'm personally much in favour of integration tests. 
> The main reason is the famous 80/20 rule. You get 80% of coverage with 20% 
> of the effort, because of the reasons you stated, you get free coverage of 
> all the other layers as well.
>
> The aforementioned MockDatabase is useful in very limited use-cases only, 
> in my opinion. I mainly implemented it
> 1. For the fun of the task.
> 2. For marketing purposes. I get many search hits because of people 
> looking for database testing ;-)
>
> The "it depends" part is caused by your general architecture. If you're 
> using H2 anyway, or if you can reasonably emulate your productive system 
> with H2, you might be able to create a binary copy of a reasonably simple 
> database and drop/recreate the database after every writing test (i.e. test 
> with side-effects in the database). Obviously, you'll also write a 
> significant amount of read-only tests, which do not affect the data.
>
> If, however, you have a huge Oracle schema, re-creating the test data is 
> costly. So... it really depends :-)
>
> I will soon blog about this topic. Curious to hear more feedback on this 
> thread.
>
> Cheers
> Lukas
>
>
>
> 2013/5/8 Stéphane Cl <[email protected] <javascript:>>
>
>> Hello,
>> I would be interested to know what strategies people are using for 
>> testing their application.
>>
>> I have started writing a prototype application and now that the 
>> requirements are more or less stable, I d'like to implement a testing 
>> strategy.
>> Previous experiences suggest that testing against a database would be the 
>> least pain. I know it's common practice to use DI and a mocking framework 
>> to simulate different scenarios but in my particular case, it seems that 
>> writing high level integration tests against a sample database would have 
>> better chances of detecting problems for more or less the same amount of 
>> work, mostly because they will go though every layer.
>>
>> However I am not sure how I should manage the sample data. I can think of 
>> the following :
>>
>> 1) Manually pre-populate a sample database with interesting cases of 
>> data. Run Junit tests directly against the sample DB while abusing 
>> transactions and rollbacks to leave the data unchanged. The sample DB 
>> creation script would be under source control so that people can easily 
>> recreate the test db and perhaps add new cases.
>> pro: may be less expensive than recreating DB and Data for every test, 
>> reasonably easy to set up.
>> con: Db may go out of sync by accident, may interfere with in-app 
>> transaction management
>>
>> 2) Maintain a sample database, use DBunit to extract datasets from it, 
>> then have it restore some tables into a known state before every test.
>> pro: no risk of corrupting test data, reasonably fast as some tests may 
>> not need a full copy of the database.
>> con: requires some work, need routines for generating its dataset files, 
>> may make schema change slightly harder. 
>>
>> 3) Use jooq record API to create the minimal amount of records in an 
>> empty DB
>> pro :  more isolation (especially if used with an in memory H2 DB with an 
>> appropriate compatibility mode), easier schema change management
>> con : may need quite a lot of manual coding for inserting data 
>>
>> Or perhaps something else, any advice or experience would be warmly 
>> welcomed.
>> Regards
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "jOOQ User Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>  
>>  
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to