Pytruth
Assertion framework for Python unit tests
Install / Use
/learn @google/PytruthREADME
PyTruth: Truth in Python
[![Development Status][development-shield]][development-link] [![Build Status][travis-shield]][travis-link] [![PyPI Version][pypi-shield]][pypi-link] [![Python Versions][pyversions-shield]][pyversions-link]
Provides unittest assertions in a fluent style. Translated from the Java implementation, google/truth.
License
PyTruth is licensed under the Apache 2.0 license.
Disclaimer
PyTruth is not an official Google product.
Contributing
Please see the guidelines for contributing before creating pull requests.
Support
PyTruth is not an actively maintained project. No support is provided.
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.
User group: pytruth-users@googlegroups.com
Installing
PyTruth can be installed using pip:
pip install pytruth
Overview
Import the truth module and alias the AssertThat() method to begin asserting
things:
from truth.truth import AssertThat
Then, instead of writing
self.assertEqual(a, b)
self.assertTrue(c)
self.assertIn(a, d)
self.assertTrue(a in d and b in d)
self.assertTrue(a in d or b in d or c in d)
with self.assertRaises(Error):
Explode()
one would write
AssertThat(a).IsEqualTo(b)
AssertThat(c).IsTrue()
AssertThat(d).Contains(a)
AssertThat(d).ContainsAllOf(a, b)
AssertThat(d).ContainsAnyOf(a, b, c)
with AssertThat(Error).IsRaised():
Explode()
Tests should be easier to read and write, and flow more clearly.
Limitations
unittest assertions accept a msg parameter to display if the assertion fails.
PyTruth has no such mechanism, though its failure messages tend to be more
informative.
The type of the subject under test (the parameter passed to AssertThat()) will
not be known until runtime, unlike Java where the type is known at compile time.
IDEs may not correctly autocomplete available predicates on an asserted subject.
In Python 2, None compares less than every other thing, except None itself.
None is less than nan, and it is less than negative infinity. Therefore, use
caution when a function might return None. The assertion
AssertThat(Func()).IsLessThan(0) succeeds whether Func() returns a negative
number or None. Instead, first check the None-ness of the return value with
IsNone() or IsNotNone() before performing an inequality assertion.
In Python 3, None is no longer comparable using < > <= >=.
PyTruth detects the version of the Python interpreter and compares or fails
appropriately, rather than allowing Python 3's TypeError to bubble up.
If the iterator over a shared value (either expected or actual) changes that value or its underlying elements, the behavior is undefined: all, none, or some of the assertions may succeed or fail, arbitrarily.
This library is threadsafe; you may execute multiple assertions in parallel.
Conversion Recipes
General
unittest | PyTruth
-----------------------------|----------------------------------------
assertEqual(a, b) | AssertThat(a).IsEqualTo(b)
assertNotEqual(a, b) | AssertThat(a).IsNotEqualTo(b)
assertTrue(a) | AssertThat(a).IsTruthy()
assertFalse(a) | AssertThat(a).IsFalsy()
assertIs(a, True) | AssertThat(a).IsTrue()
assertIs(a, False) | AssertThat(a).IsFalse()
assertIs(a, b) | AssertThat(a).IsSameAs(b)
assertIsNot(a, b) | AssertThat(a).IsNotSameAs(b)
assertIsNone(a) | AssertThat(a).IsNone()
assertIsNotNone(a) | AssertThat(a).IsNotNone()
assertIn(a, b) | AssertThat(a).IsIn(b)
assertIn(a, [b, c, d]) | AssertThat(a).IsAnyOf(b, c, d)
assertNotIn(a, b) | AssertThat(a).IsNotIn(b)
assertNotIn(a, [b, c, d]) | AssertThat(a).IsNoneOf(b, c, d)
assertIsInstance(a, b) | AssertThat(a).IsInstanceOf(b)
assertIsNotInstance(a, b) | AssertThat(a).IsNotInstanceOf(b)
assertTrue(hasattr(a, b)) | AssertThat(a).HasAttribute(b)
assertFalse(hasattr(a, b)) | AssertThat(a).DoesNotHaveAttribute(b)
assertTrue(callable(a)) | AssertThat(a).IsCallable()
assertFalse(callable(a)) | AssertThat(a).IsNotCallable()
Truthiness
PyTruth supports a finer grained distinction of truthiness than unittest does.
In particular, it differentiates between "is True" and "is truthy."
unittest's assertTrue(x) is equivalent to assertIs(bool(x), True),
and its assertFalse(x) is equivalent to assertIs(bool(x), False).
PyTruth's IsTrue() and IsFalse() predicates match only the boolean
subjects True and False themselves.
Therefore it is important not to blindly convert assertTrue() to IsTrue(),
and likewise with assertFalse() and IsFalse().
Truthy assertion | Result | Falsy assertion | Result
------------------------------|----------|-------------------------------|---------
assertTrue(True) | succeeds | assertFalse(False) | succeeds
assertTrue(1) | succeeds | assertFalse(0) | succeeds
assertTrue(None) | fails | assertFalse(None) | succeeds
AssertThat(True).IsTrue() | succeeds | AssertThat(False).IsFalse() | succeeds
AssertThat(1).IsTrue() | fails | AssertThat(0).IsFalse() | fails
AssertThat(None).IsTrue() | fails | AssertThat(None).IsFalse() | fails
AssertThat(True).IsTruthy() | succeeds | AssertThat(False).IsFalsy() | succeeds
AssertThat(1).IsTruthy() | succeeds | AssertThat(0).IsFalsy() | succeeds
AssertThat(None).IsTruthy() | fails | AssertThat(None).IsFalsy() | succeeds
Strings
unittest | PyTruth
---------------------------------------------------------------|---------------------------------------
assertEqual(len(s), n) | AssertThat(s).HasLength(n)
assertTrue(s.startswith('a')) | AssertThat(s).StartsWith('a')
assertTrue(s.endswith('a')) | AssertThat(s).EndsWith('a')
assertRegex(s, r)<br>assertRegexpMatches(s, r) | AssertThat(s).ContainsMatch(r)
assertNotRegex(s, r)<br>assertNotRegexpMatches(s, r) | AssertThat(s).DoesNotContainMatch(r)
assertRegex(s, '^r')<br>assertRegexpMatches(s, '^r') | AssertThat(s).Matches('r')
assertNotRegex(s, '^r')<br>assertNotRegexpMatches(s, '^r') | AssertThat(s).DoesNotMatch('r')
Matching strings
The r parameter passed to the matching functions may either be a
r'raw string', or a pattern object returned from re.compile().
Numbers, strings, and other comparable things
unittest | PyTruth
---------------------------|---------------------------------
assertLess(a, b) | AssertThat(a).IsLessThan(b)
assertGreater(a, b) | AssertThat(a).IsGreaterThan(b)
assertLessEqual(a, b) | AssertThat(a).IsAtMost(b)
assertGreaterEqual(a, b) | AssertThat(a).IsAtLeast(b)
Numbers
unittest | PyTruth
--------------------------------------|-------------------------------------
assertEqual(a, 0) | AssertThat(a).IsZero()
assertNotEqual(a, 0) | AssertThat(a).IsNonZero()
assertEqual(a, float('inf')) | AssertThat(a).IsPositiveInfinity()
assertEqual(a, float('-inf')) | AssertThat(a).IsNegativeInfinity()
assertFalse(a.isinf() or a.isnan()) | AssertThat(a).IsFinite()
assertTrue(a.isinf() or a.isnan()) | AssertThat(a).IsNotFinite()
assertTrue(a.isnan()) | AssertThat(a).IsNan()
assertFalse(a.isnan()) | AssertThat(a).IsNotNan()
assertAlmostEqual(a, b, delta=d) | AssertThat(a).IsWithin(d).Of(b)
assertNotAlmostEqual(a, b, delta=d) | AssertThat(a).IsNotWithin(d).Of(b)
Lists, strings, and other iterables
unittest | PyTruth
--------------------------------|---------------------------------------------
assertEqual(len(a), n) | AssertThat(a).HasSize(n)
assertEqual(len(a), 0) | AssertThat(a).IsEmpty()
assertGreaterThan(len(a), 0) | AssertThat(a).IsNotEmpty()
assertIn(b, a) | AssertThat(a).Contains(b)
assertNotIn(b, a) | AssertThat(a).DoesNotContain(b)
assertTrue(b in a and c in a) | AssertThat(a).ContainsAllOf(b, c)<br>AssertThat(a).ContainsAllIn([b, c])
assertTrue(b in a or c in a) | AssertThat(a).ContainsAnyOf(b, c)<br>AssertThat(a).ContainsAnyIn([b, c])
assertTrue(b in a and c in a and len(a) == 2) | AssertThat(a).ContainsExactly(b, c)
assertCountEqual(a, b)<br>assertItemsEqual(a, b) | `AssertThat(sorted(a)).ContainsExactlyEle
