Conversation
|
The tests probably won't succed (becuase there is no migration code in this PR.). |
| ) | ||
|
|
||
| func TestCreateLoadDeleteListWI(t *testing.T) { | ||
| doWithTransaction(t, func(ts *models.GormTransactionSupport) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How many things are we testing at once? Wouldn't it be better to split it to more focused, descriptive tests? This test itself has too many reasons to fail in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why that is a bad thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Hard to reason what the test is about
- It tests too many things at once - as method already suggests.
- If something stops working you will go through snow-ball trying to fix every single failing assertion one after the other
Is it good enough or still not convinced?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea that you just have to look at a test to know what is broken is a red herring in most cases. You'll have to reproduce and debug the code anyway. The target code of this test is colocated and highly coupled. I don't want to copy/paste the setup code x times just to satisfy an abstract notion of niceness. Our guidelines should favor easy & fast writing of tests.
What I'm saying is splitting this test method into 5 different ones will not increase coverage and it won't allow us to debug failures faster. At least I'm convinced of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea that you just have to look at a test to know what is broken is a red herring in most cases
Not from my experience.
I don't want to copy/paste the setup code x times just to satisfy an abstract notion of niceness.
Don't you have something like beforeEach or "extract to function" to easily fix it?
As I'm not really part of the core team I won't continue this discussion further, but I truly believe that this is not the way how the code should be written at all. It will get hard to maintain later to start with. And coverage should be just a supportive metric for your tests, not the goal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A Test failure can be seen as a Bug Report, the more fine-grained/detailed the failure report is the easier it is to reason about and put you on the right track to fix it.
In the current state a test failure says; 'something wrong with WI'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that's a good read http://xunitpatterns.com/Test%20Smells.html
| if err != nil { | ||
| panic("Failed to connect database: " + err.Error()) | ||
| } | ||
| defer db.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't defer be before panic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, if opening the db fails, it's not open.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it the only reason to fail here?
| if err := ts.Begin(); err != nil { | ||
| panic(err.Error()) | ||
| } | ||
| defer ts.Rollback() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as before, shouldn't defer be before panic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway what's the point of the transaction here if we anyway rollback before it even hits the database?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To leave no traces of the test in the database.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then why do we need the database at all? Shouldn't we commit and clean-up for each and every test before we start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the database because writing stuff to the database is what we're testing. Rolling back the transaction is the simplest way to write tests without having side effects in the db.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the transaction isolation level we are using?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens to the actual DB depends highly on the DB Driver. If you take Hibernate/JDBC as an example, create the object and fetch the object from PersistenceContext might never actually flush anything to the DB unless you commit. DB operation tests should always split Write and Read in two different TX (if TX is required at all) to ensure we actually hit the DB.
The idea that Rollback DB on test end actually work is bogus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you are saying is true in the case of Hibernate. Usually, you can force writes to the DB by calling some kind of flush() method, though.
The problem with committing the changes is that it makes side-effect free tests impossible: sooner or later you'll end up with spurious failures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see several advantages of not leaving a trace by doing a rollback
- little to no need of cleanup before the test
- ability to run the tests in parallel, especially those which share the schema
but I think both of these are still possible to address when doing a commit.
However, my main question is - does the thing we are testing here, with rollback (and maybe flushing) reflects what's going on on production? If not such a test is simply a waste, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't actually call it a waste...many unit tests have little to do with what happens in production (for example, because they mock certain systems away). That doesn't mean they are not testing anything. Same here...even while some things may go wrong at commit time a large number of codepaths are tested.
In the worst case that stuff would go wrong at commit time, you may get false negatives, but you won't get false positives, so if the test fails, you are certain that something is wrong. On the other hand, if the test succeeds, you are not sure it will not fail in production.
But anyway...no quite sure how we would implement idempotent tests while committing changes to the database.
b9de4d1
to
c7f9ca7
Compare
c7f9ca7
to
4df1cbb
Compare
Current coverage is 64.74% (diff: 100%)@@ master #294 diff @@
==========================================
Files 45 45
Lines 1936 1940 +4
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
+ Hits 1244 1256 +12
+ Misses 560 554 -6
+ Partials 132 130 -2
|
33a98f6
to
3ecc4b3
Compare
3ecc4b3
to
85bbac5
Compare
|
@bartoszmajsak @aslakknutsen Do we still need this ? what is its state ? |
|
Closing this PR! we don't need it anymore |
Issue #293