In "agile projects" it is common to use user stories to describe what has to be done. But it is also common to use constraints to describe things that cannot be described in a user story. This can be things like:
Constraints are things that should always be considered during every user story implemented.
However sometimes people come along with things that sound like constraints but they're not. For example:
This is a bad constraints since it have no goal. You might think you improve the constraint if you say:
This is still a bad constraint since you probably have a release date. What happens if the constrained time is not enough to achieve the goal?
I think that if there is a known problem (for example some responses take more than one second) you should add user stories (or bugs) for that and prioritize and plan the fixes for those problems just like anything else. And if you have no known problems you should just set up constraints telling the team what kind of quality you want. If it takes the team 50% of the velocity to pass all the constraints you should let them do so since otherwise you'll have to let them do it later anyway. Either way you'll notice the team are struggling to pass all the constraints and maybe they are to strict. But if you time box them from the start you will notice this later than if you force the team to always deliver more or less release quality.
Measuring code coverage is often perceived as a good measure of test quality. It is not. Good tests finds problems when changes are made to the code. But if you just want to have large code coverage you can easily make a number of tests calling all your methods but not checking the results. The only thing high code coverage values really tell you is that the code is at least not crashing with the given input.
If you however are using BDD/TDD, code coverage values might be of interest. For example if you do not have 100% function coverage (i.e. not 100% of the functions are called) then you aren't really using BDD/TDD are you? Because how could you write a method that is not called by anyone? Well actually you might have created methods that are never called by your tests. Many TDD practitioners use a rule "to simple to test" which applies to real simple, property like methods. I don't really like that philosophy, but more on that in a later post.
So now you think with 100% function coverage you will also have 100% line coverage with BDD/TDD, right? Well, yes and no. Typically you don't since you will add error handling with logging methods that will never occur since the errors never occur in your tests. It might be that you open a file and if that fails you log an error and exit your application. This never happens in the tests since you always manage to open the file in your tests. So how did those lines get in there if never called? Well one other rule often used by TDD practitioners is that you "should not do stupid things". If a system call may fail, you check the result regardless of tests or not. With dependency injection you'll probably get close to 100% but there is no point in bending back-wards in order to achieve high code coverage.
Does this mean there is no point in measuring code coverage? I think it is great to measure code coverage if you use the result correctly. You should not add more tests just to increase coverage since test added just to increase coverage tend to just exercise code and not really testing something interesting. But low code coverage when using BDD/TDD is definitely a warning signal that something is wrong. The team is not using the methodology correctly. So what is considered OK coverage levels? From personal experience I think anything below the levels listed in the table below should be considered bad since type without injectiontype withoutinjection with with you should have no problem at all achieving the given values.
But sometimes there is someone (usually a manager) that thinks coverage should be above some level. So even though you know those tests will not really be useful you have to add more tests for coverage. What do you do? Either you can try to ignore the coverage fact and just try to add more tests, testing interesting things. Or you could try using Pex. Pex is a tool from Microsoft Research that is an automated exploratory testing tool. It can be used to make a small test suite with high code coverage and with only a few simple examples I get the impression it is quite good at finding border cases in your code. This will not however replace your traditional tests/specifications written as part of your TDD/BDD process. But it can help you test some cases you did not think of and that way increase code coverage even more without any extra effort from you. At least it is better than adding coverage tests by hand.
And if you listened to me and started to write nice looking SQL, maybe you wanna look ate making your C# code look nice too...
I read this article on SQL Code Layout and Beautification and can only agree with the author that other people's SQL often is hard to understand because I'm so used to how I write my SQL statements. One of the links is to an on-line tool formatting your SQL according to a number of rules. I was happy to find that my way of writing SQL was supported:
SELECT a, b, c AS d FROM x, y, z AS w WHERE a = 2 AND b IN (3,4,7)
And another example:
SELECT obj.run, obj.camcol, STR(obj.field,3) AS field, STR(obj.rowc,6,1) AS rowc, STR(obj.colc,6,1) AS colc, STR(dbo.FOBJ(obj.objid),4) AS id, STR(obj.psfmag_g - 0 * obj.extinction_g,6,3) AS g, STR(obj.psfmag_r - 0 * obj.extinction_r,6,3) AS r, STR(obj.psfmag_i - 0 * obj.extinction_i,6,3) AS i, STR(obj.psfmag_z - 0 * obj.extinction_z,6,3) AS z, STR(60 * distance,3,1) AS d, dbo.FFIELD(neighborobjid) AS nfield, STR(dbo.FOBJ(neighborobjid),4) AS nid, 'new' AS 'new' FROM (SELECT obj.objid, run, camcol, field, rowc, colc, psfmag_u, extinction_u, psfmag_g, extinction_g, psfmag_r, extinction_r, psfmag_i, extinction_i, psfmag_z, extinction_z, nn.neighborobjid, nn.distance FROM photoobj AS obj JOIN neighbors AS nn ON obj.objid = nn.objid WHERE 60 * nn.distance BETWEEN 0 AND 15 AND nn.mode = 1 AND nn.neighbormode = 1 AND run = 756 AND camcol = 5 AND obj.TYPE = 6 AND (obj.flags & 0x40006) = 0 AND nchild = 0 AND obj.psfmag_i < 20 AND (g - r BETWEEN 0.3 AND 1.1 AND r - i BETWEEN -0.1 AND 0.6)) AS obj JOIN photoobj AS nobj ON nobj.objid = obj.neighborobjid WHERE nobj.run = obj.run AND (ABS(obj.psfmag_g - nobj.psfmag_g) < 0.5 OR ABS(obj.psfmag_r - nobj.psfmag_r) < 0.5 OR ABS(obj.psfmag_i - nobj.psfmag_i) < 0.5)ORDER BY obj.run, obj.camcol, obj.field
I don't know what's worse; making crosswords with only SQL related questions (requires free registration to access) or actually trying to solve the same. This is one of many thing that currently puzzles me. One other thing that also scares me is that I get annoyed when I cannot solve these crosswords right away...
When looking at BDD and TDD examples it is very common to see the use of mock objects in the code. This however strikes me as a little bit strange since I think you should use stubs and not mocks when working with BDD/TDD. A mock is basically a stub with the added knowledge that a mock object knows how it is expected to be used. In my opinion this fact disturbs the focus when applying BDD/TDD. Additionally I think maintainability is decreased since the tests will now have a dependency on implementation internals and you risk having to change your test not because the API has changed but how things are done internally.
Let me explain what I mean with an example. Consider a data object used to handle transactions and the ability to read and modify the amount money on a given bank account. Now assume this data object is used as a parameter to a transfer method that is used to transfer funds between two accounts. One way to implement the transfer method could be:
From a maintainability point of view I think mocking the data object will be risky since the mock will verify that the correct number of calls are made in the correct order. It wouldn't surprise me if we some day saw a new transfer implementation looking something like this:
The example may seem a little far-fetched but still I think it points toward a maintainability risk involved when using a mock. But OK, let's assume that maintainability will not be a problem. We're still shifting focus from what is important I think. As soon as a mock is involved when I write my test/scenario I do not only have to think about the behavior I expect. I must also think about how my mock will be used since that may or may not affect my test code. Using stubs instead of mocks will reduce that focus shift since stubs are just doing what they're told without regard of context.
Sure one might argue that using stubs will also involve having to think about how the stub is used. That is true but without the risk of having order or number of calls to the stub mess up your test/scenario setup. And the less time you spend on thinking about setup and the more you spend on defining behavior, the better I think. And thinking about behavior of internals and/or dependent objects should just be kept to an absolute minimum if you ask me.
Yesterday I attended a presentation at Tobii on how they've implemented Scrum in one of their development teams. The presentation was started by Henrik Kniberg who gave a short introduction to Scrum. I do not envy his task since a quick poll showed that more than half of the audience was practicing Scrum in their current project. One thing that always amazes me at these kind of presentations are the two or three persons attending who think that Scrum is a silver bullet solution to all problems and who ask all kinds of questions related to their current situation trying to figure out what they have to do in order to make their Scrum implementation more successful. What they don't seem to get is that Scrum is not the answer to your problems - it just helps you see your problems. You still have to solve the problems yourself!
But back to Tobii. We got a great demo on what eye tracking software can be used for,including playing FPS games. And I must say it was extra interesting for me to see what the team was really developing since I was the person brought in to coach them when they wanted to start using Scrum. I attended daily scrums, sprint demos and retrospectives but I never got a chance to see and understand what they really accomplished.
So how did they implement Scrum? I would say they pretty much implemented vanilla scrum from out of the box I would say. But this is usually not enough to successfully implement Scrum I would say. In their case I think the following things were the keys to success:
So what can you learn from this? Well, doing great stuff is always easy when you have great people to work with. The team I worked with at Tobii had all the best prerequisites for success and that is one thing you either have or you haven't. But what you can do is to use a coach. Having the ability to discuss different matters with someone outside of your regular workmates as well as having somebody that easily can say those things everybody want to say but are afraid to say can in some cases be what makes or break your implementation of Scrum.
Previously I've written about where to start when applying agile to your project. But not all people are happy with that since they want to read a book. Fair enough - I also started out reading books when agile cached my interest. So people I know tend to ask me what books I recommend to someone who wants o learn more. Typically they ask for a book on Scrum but that is not really what they want. They want a book to help them work better in their project.So this is my prioritized list on books to read when you want to learn more and implement agile into your project successfully. It is prioritized so if you only read one book, read the first one and then add more reading as you have time.
Of cause there are more books on certain topics like TDD but that is not the typical question I get. So I'll leave such books for a future list. Maybe.