class MyTestableClass {
fun `methodName - when input does not parse to valid regex throw exception`() {
}
}
It's pretty clear what is under test in a situation like that. That's basically the only situation I ever see it used in (and would code-smell the heck out of it if I saw it in other circumstances).People who are familiar with RSpec-style testing are very used to this sort of thing.
describe MyTestableClass do
context 'input parsing issues' do
context 'when not valid regex' do
it 'throws exception' do
...
end
end
end
end
Anecdotally, I've also found that such style naming for tests allows me to write out the desired names for all the tests ahead of time more easily and then implement them. That happens to be my flow.They did a study and it isn't hard to read camelCase. https://ieeexplore.ieee.org/document/5090039
It's important to note that the researchers only tested short phrases with 2 and 3 words. "getNextPath" is a different beast compared to "methodName_whenInputDoesNotParseToValidRegexThrowException".
On the other hand, there is a good body of research that generally shows that proper sentences (not just 2-3 words) without spaces are harder to read, at least for English speakers[1]. Early medieval Latin manuscripts did not use space between words[2]. The fact that spaces were seen as an improvement when they were introduced, is probably telling.
[1] https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=unsp...
[2] Roman-era inscriptions did use an interpunct (a small middle dot) to separate words, but this practice fell out of fashion in Late Antiquity and Early Middle Ages and I'm not sure if it was ever the norm in handwriting.
That study compared camel case to underscore spaces. Well underscore space is still not as readable as methods with spaces and dashes.
The study does not say that camelCase is unequivocally as easy, or easier, to read.
Selecting the correct identifier from a list of 2-3 words (expandAliasTable, expandAliasTitle, etc.) is a wholly different exercise.
@ParameterizedTest
@ValueSource(strings = {"first", "second"})
void fooGoesBar(String param) {
...
}
Also, once you get used to assertj, you'll never want single-assert again. It's fantastically useful to know (for example) not just that two lists aren't equal, but specifically what elements differ.Pytest shows the diff as well when using assert:
> assert y == x
E assert [1, 2, 3] == [1, 4, 3, 6]
E
E At index 1 diff: 2 != 4
E Right contains one more item: 6
E Use -v to get more diff assertThat(someCollection).map(Thing::getValue).containsExactlyInAnyOrder(3, 4, 5); assert sorted(x) == sorted(y)
If you want to add map, then you have to write assert list(sorted(i.getValue() for i in someCollection)) == [3, 4, 5]
If the list contains non-sortable values, but they are hashable and unique, you can use sets: assert set(x) == set(y)
If the values are not unique, but hashable, you can use a counter (like a set but with count for repeating values): assert Counter(x) == Counter(y)
(by the way I learned about this trick from a LLM)And if the values are neither sortable, nor hashable, you'll have to write a helper function.
But still, pytest tests are less wordy and they don't require you to create a class.
This situation is familiar to me, I had to write such helper function when writing tests in PHP, for some reason it is not included in PHPUnit assertions.
In fact I've occasionally found myself writing reflection code to parse the test method name as input just to avoid that problem altogether (for name and data, not for documentation). And that was in plain Java even, the pattern could be far more useful with that kotlin naming freedom.
When a test fails, the method name describes what it was supposed to do written out like a sentence enclosed in double quotes which seems like a win but not much of one.
When you need to add a new test or analyze if an existing test needs to be changed, you have to eyeball all the code in the test class because even with methods named with spaces, it's not always indicative of what it does.
With Java, I can sort a list of method names and have a better idea immediately what needs to be updated or added.
Refactoring Spock tests sucks due to how the context is different based on the clause you’re in.
expectInternalServerErrorOnBadInput
Vs
expect internal server error on bad input