0

I recently found Googles pytruth package. I am very used to pytest and I am wondering what the value of the way less commonly used pytruth is. The only reason why I didn't directly discard it, is that it comes from Google.

From the README, it seems to be mainly (only?) that you have the following ways to write assertions:

AssertThat(a).IsEqualTo(b)  # 1
AssertThat(c).IsTrue()  # 2
AssertThat(d).Contains(a)  # 3
AssertThat(d).ContainsAllOf(a, b)  # 4
AssertThat(d).ContainsAnyOf(a, b, c)  # 5
with AssertThat(Error).IsRaised():  # 6
  Explode()
AssertThat(result).ContainsExactlyElementsIn(expected)  # 7

I am used to write the following:

assert a == b  # 1
assert c  # 2
assert a in d  # 3
for element in [a, b]:  # 4
    assert element in d
assert any(element in d for element in [a, b, c])  # 5
with pytest.raises(Exception):  # 6
    Explode()
assert set(result) == set(expected)  # 7

Is there any difference between what I was doing and the truth package? Is there any reason to use the truth package? Is it maybe even considered good style?

1

Which way you find more readable, the pytruth ot the pytest way propably comes down to what you are used to. If you are used ot Java, you will find that more readable.

It is shared with the community to bring an expressive, consistent assertion style to projects that may be using a combination of unittest, abseil, googletest, mox, and mock—especially to people familiar with Java Truth.

(quoted from the pypilink)

JavaTruth, there we have it. So then, if you have to maintain Java and Python applications, this may be worth it to you for improved consistency.

As far as I see it, pytruth can be used with any testing framework. If you use pytest, you are locked in the whole framework. So if you want something different than pytest, you can use pytruth on top. If you are already bought into pytest, I'd personally rather prefer the way pytest handles asserts

5

Some of these, particularly 4, 5 and 7 are "clearly" more readable in the fluent truth style - the assertion days exactly what it does, no brainpower required. It is also worth noting that your #7 does not match the truth example: think about what happens if d contains an element foo. Sure, you can fix it, but if you got it wrong writing the question, would you get it wrong writing production code as well?

  • I changed 7 - I didn't know what the "Exactly" of pytruth does. So this undermines the point that it is more readable. – Martin Thoma Sep 4 at 6:20
  • But is it really only about readability or does pytruth offer something I missed? – Martin Thoma Sep 4 at 6:21
  • 1
    Particularly when it comes to test code, readability is everything. And I still find PyTruth much more readable than set(a) == set(b). – Philip Kendall Sep 4 at 7:14
  • 2
    And note your example 7 is still wrong. Consider result = [1, 2, 1] and expected = [1, 2]. – Philip Kendall Sep 4 at 7:31
  • For example 7: I think this depends very much on what you want. With set, it is clear to me what I get and I would expect those two (result = [1, 2, 1] and expected = [1, 2]) to be considered the same. result contains the same elements as expected and vice versa. Just not the same amount. From the name ContainsExactlyElementsIn, it was not clear to me that this is considered to be different. – Martin Thoma Sep 4 at 8:17
3

According to the documentation, PyTruth claims to have more informative failure messages than some other widely-used testing frameworks in Python. (This is of course a subjective measure.)

Failure messages are very important in unit testing, and even more so in Test-Driven Development, where the failure message actually partially drives the implementation. ("Do the simplest thing that could change the failure message.")

  • Do you know an example where the error message of pytruth is supposed to be better than the one of pytest? – Martin Thoma Sep 4 at 6:53
  • 3
    Just try your example 7. With raw assert: AssertionError. With PyTruth: truth.truth.TruthAssertionError: Not true that <[1, 3]> contains exactly <[1, 2]>. It is missing <[2]> and has unexpected items <[3]>. That's completely night and day as to clarity, assert tells me nothing at all, PyTruth tells me exactly what I need to know. – Philip Kendall Sep 4 at 7:33
  • 2
    I think pytest does give perfectly readable results with the default assert: gist.github.com/MartinThoma/62998b958923b0aa4e75adc9984826fd – Martin Thoma Sep 4 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.