This site lists the protips that we shared with students during our courses
You might have read, or heard us, say that:
Let the tests guide you, but what does that mean?
In this blog post I wanted share a few thoughts and tips on how this can be used.
First the tests are the first user of your code and it can be a great guide, like documentation, for someone calling your code. Consider a weekend test that tells you something like:
- Create a method called `isApa`
- Return `true` if the passed in argument is `apa`
- Return `false` if the passed in argument is anything else than `apa`
This text have a lot of ambiguities… but the tests does not. Look at the tests, that you always get from the weekend tests. (Here in JavaScript)
const assert = require('assert');
const app = require('./index');
describe('isApa', () => {
it('is true for apa', () => assert.strictEqual(app.isApa('apa'), true));
it('is false for banan', () => assert.strictEqual(app.isApa('banan'), false));
it('is false for 12', () => assert.strictEqual(app.isApa(12), false));
it('is false for blank', () => assert.strictEqual(app.isApa(''), false));
it('is false for null', () => assert.strictEqual(app.isApa(null), false));
});
(And an example in c#-
[Fact]
public void a_first_test_for_isApa()
{
// arrange
var solution = new Solution();
// act
var result = solution.IsApa('apa');
// assert
result.Should().Be(true);
}
)
See - the tests are much more concrete and gives you a lot of more information. If you didn’t understand the text, use the code and see if that makes more sense.
Also, in real code (as in not weekend tests), you could document your own understanding using by adding more tests.
Another thing that tests can be useful for is to understand how the method is supposed to work.
Here’s another example from the first days of the bootcamp.
it('should run function if ID exist in location hash', done => {
const hash = '#id=5';
players.ifIdExist(hash, i => {
assert.equal('5', i);
done();
});
});
From this code, although we don’t know much about it, we can deduce quite a lot by looking at it:
players
that has a function ifIdExists
hash
that is a string, and a function starts with i => {...
to });
(This is a callback function)hash
-string is #id=5
we expect to get an i
that is equal to the string 5
pure
function. More on this later.That’s quite a lot that we know about this. Now we can figure out what the function should do; it should parse #id=5
to 5
and call the passed in callback-function passing the 5
as parameter to the callback.
But now we where “lucky” because the function was pure. Let’s consider an example of an unpure function and see that we don’t get as much information about what the function should do.
it('should set location hash', () => {
const element = document.querySelector('#test');
players.playerData(element, id, playerEntity);
assert.equal('#id=3', window.location.hash);
});
This function has a few things that we don’t really see;
document
- looks like a JavaScript DOM object to me (with the querySelector('#test')
). This means that we somehow need to set a document. Can we find where this happens in the test file? (Psst - yes, it’s above… in our example)playerEntity
- what is that? Turns out that it’s also defined outside the test… Let’s find it and see what it iswindow.location.hash
… so that means that window.location.hash
needs to be manipulated somehow.It’s a bit weird though because it seems to me like the players.playerData
function is doing two things… Something with the element
being passed in and then the window.location.hash
should be handled.
It’s getting a bit more complicated to understand what the function does, but by carefully reading the tests we can still figure out what we are supposed to do.
Use the tests as a guide means that you can get quite a lot of help in figuring out what the code is supposed to do.
And, in the examples above there are just a few cases. Adding more test will tell you even more about how the code is supposed to be used. Or document how you intend the code to be used, for the next developer. Oh yeah - that’s you… six months.