Bot releases are visible (Hide)
This release is the final step of copying all our methods from Truth8
to Truth
. If you have not already migrated your usages from Truth8
to Truth
, you may see build errors:
OptionalSubjectTest.java:39: error: reference to assertThat is ambiguous
assertThat(Optional.of("foo")).isPresent();
^
both method assertThat(@org.checkerframework.checker.nullness.qual.Nullable Optional<?>) in Truth8 and method assertThat(@org.checkerframework.checker.nullness.qual.Nullable Optional<?>) in Truth match
In most cases, you can migrate your whole project mechanically: git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'
. (You can make that change before upgrading to Truth 1.4.2 or as part of the same commit.)
If you instead need to migrate your project incrementally (for example, because it is very large), you may want to upgrade your version of Truth incrementally, too, following our instructions for 1.3.0 and 1.4.0.
Please feel welcome to open an issue to report problems or request help.
Truth.assertThat(Stream)
and Truth.assertThat(Optional)
. This can create build errors, which you can fix by replacing all your references to Truth8
with references to Truth
. (45782bd0e)Published by cpovirk 8 months ago
This release deprecates Truth8
.
All its methods have become available on the main Truth
class. In most cases, you can migrate your whole project mechanically: git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'
While we do not plan to delete Truth8
, we recommend migrating off it, at least if you static import assertThat
: If you do not migrate, such static imports will become ambiguous in Truth 1.4.2, breaking your build.
Published by cpovirk 9 months ago
In this release, our assertions on Java 8 types continue to move from the Truth8
class to the main Truth
class. This change should not break compatibility for any supported JDK or Android version, even users who test under old versions of Android without API desugaring. Additionally, we will never break binary compatibility, though some users will have to make changes to their source code in order for it to compile against newer versions.
This release is likely to lead to more build failures than 1.3.0 did. However, those failures should be straightforward to fix.
Foo.java:152: error: reference to assertThat is ambiguous
assertThat(repo.findFileWithName("foo")).isNull();
^
both method assertThat(@org.jspecify.nullness.Nullable Path) in Truth8 and method assertThat(@org.jspecify.nullness.Nullable Path) in Truth match
In the same commit:
import static com.google.common.truth.Truth8.assertThat;
with import static com.google.common.truth.Truth.assertThat;
.
import com.google.common.truth.Truth8.assertThat
with import com.google.common.truth.Truth.assertThat
.import com.google.common.truth.Truth8;
with import com.google.common.truth.Truth;
.
Truth8
with references to Truth
.
Truth8.assertThat(optional).isPresent()
with Truth.assertThat(optional).isPresent()
.If you're feeling lucky, you can try this one-liner for the code updates:
git grep -l Truth8 | xargs perl -pi -e 's/import static com.google.common.truth.Truth8.assertThat;/import static com.google.common.truth.Truth.assertThat;/g; s/import com.google.common.truth.Truth8.assertThat/import com.google.common.truth.Truth.assertThat/g; s/import com.google.common.truth.Truth8/import com.google.common.truth.Truth/g; s/\bTruth8[.]/Truth./g;'
In most cases, that can be further simplified to:
git grep -l Truth8 | xargs perl -pi -e 's/\bTruth8\b/Truth/g;'
After that process, it is possible that you'll still see build errors from ambiguous usages of assertThat
static imports. If so, you can find a workaround in the section about overload ambiguity in the release notes for 1.3.0. Alternatively, you can wait to upgrade until after a future Truth release, which will eliminate the ambiguity by changing the signatures of some Truth.assertThat
overloads.
If you have a very large repo or you have other reasons to prefer to upgrade incrementally, you can use the approach that we used inside Google. Roughly, that approach was:
Truth8.assertThat
, change them to avoid static import.
assertThat(optional).isPresent()
with Truth8.assertThat(optional).isPresent()
.Truth8
with references to Truth
(including restoring static imports if desired), as discussed in section about the simple upgrade strategy above.assertWithMessage(...).about(intStreams()).that(...)
, expect.about(optionalLongs()).that(...)
, or similar, you can remove your call to about
. This change will never be necessary; it is just a simplification.
streams
and optionals
, whereas 1.4.0 solves it for the other Truth8
types.Please feel welcome to open an issue to report problems or request help.
Truth8.assertThat
overloads to the main Truth
class. (9be8e774c, 1f81827f1)that
overloads to make it possible to write type-specific assertions when using the remaining Java 8 types. (7c65fc611)Published by cpovirk 9 months ago
In this release, our assertions on Java 8 types begin to move from the truth-java8-extensions
artifact and the Truth8
class to the main truth
artifact and the Truth
class. This change should not break compatibility for anyone, even users who test under old versions of Android without API desugaring. Additionally, we will never break binary compatibility, though some users will have to make changes to their source code in order for it to compile against newer versions.
This change will be routine for most users, but we're providing as much information as we can for any users who do encounter problems.
We will post fuller instructions for migration later on, once we've learned more from our internal migration efforts. For now, you may find that you need to make one kind of change, and you may elect to make others. (If we missed anything, please open an issue to report problems or request help.)
The change you might need to make:
Truth.assertThat
, we cause some code to fail to compile because of an overload ambiguity. This is rare, but it can happen if you static import both Truth.assertThat
and some other assertThat
method that includes overloads for Optional
or Stream
. (It does not happen for Truth8.assertThat
, though, except with the Eclipse compiler. Nor it does necessarily happen for other assertThat(Stream)
and assertThat(Optional)
methods.) If this happens to you, you'll need to remove one of the static imports, changing the corresponding call sites from "assertThat
" to "FooSubject.assertThat
."
Truth.assertThat
overloads. Once we make those further changes, you may be able to simultaneously replace all your imports of Truth8.assertThat
with imports of Truth.assertThat
as you upgrade to the new version, likely without introducing overload ambiguities.The changes you might elect to make:
If you use Truth8.assertThat(Stream)
or Truth8.assertThat(Optional)
, you can migrate to the new overloads in Truth
. If you static import Truth8.assertThat
, you can usually make this change simply by replacing that static import with a static import of Truth.assertThat
—or, if you already have an import of Truth.assertThat
, by just removing the import of Truth8.assertThat
. (If you additionally use less common assertion methods, like assertThat(OptionalInt)
, you'll want to use both imports for now. Later, we'll move assertThat(OptionalInt)
and friends, too.) We recommend making this change now, since your calls to Truth8.assertThat
will fail to compile against some future version of Truth, unless you plan to wait to update your Truth dependency until we've made all our changes for Java 8 types.
If you use assertWithMessage(...).about(streams()).that(...)
, expect.about(optionals()).that(...)
, or similar, you can remove your call to about
. This change will never be necessary; it is just a simplification.
If you depend on truth-java8-extension
, you may remove it. All its classes are now part of the main truth
artifact. This change, too, is not necessary; it is just a simplification. (OK, if your build system has a concept of strict deps, there is a chance that you'll need to add deps on truth
to replace your deps on truth-java8-extension
.)
Finally, the changelog for this release:
StreamSubject
avoid collecting the Stream
until necessary, and made its isEqualTo
and isNotEqualTo
methods no longer always throw. (f8ecaec69)assertThat
overloads for Optional
and Stream
to the main Truth
class. (37fd8bea9)that
overloads to make it possible to write type-specific assertions when using expect.that(optional)
and expect.that(stream)
. (ca7e8f4c5)truth-java8-extension
classes into the main truth
artifact. There is no longer any need to depend on truth-java8-extension
, which is now empty. (We've also removed the Truth8
GWT module.) (eb0426eb7)Again, if you have any problems, please let us know.
Published by cpovirk 10 months ago
Any
messages. This fix may cause tests to fail, since ProtoTruth will now check whether the message contents match. If so, you may need to change the values that your tests expect, or there may be a bug in the code under test that had been hidden by the Truth bug. Sorry for the trouble. (8bd3ef613)isWithin().of()
support to IntegerSubject
and LongSubject
. (6464cb5ca, 0e99a2711)Published by cpovirk over 1 year ago
IterableOfProtosSubject
to produce a proper failure message instead of NPE when the actual value is null
.Published by cpovirk over 1 year ago
-source 8 -target 8
. This means that it no longer runs under Java 7 VMs. It continues to run under Android, even old versions, for all apps that have enabled support for Java 8 language features. (db5db2429)value of: method()
to expect.that
, matching the existing support for assertThat
. (bd8efd003)IterableSubject.containsAtLeastElementsIn().inOrder()
to print an extra line that shows only the expected elements in their actual order. (9da7dd184)Published by cpovirk over 3 years ago
comparingExpectedFieldsOnly()
handles oneof
fields. (f27208428)comparingExpectedFieldsOnly
to work when required fields are absent. (f27208428)Subject.toString()
to throw UnsupportedOperationException
. (fa4c7b512)Published by cpovirk over 3 years ago
This release completes the feature that I got wrong in 1.1.1 -- the ability to exclude our JUnit 4 dependency and still use standard Truth assertions.
Expect
, ExpectFailure
, and TruthJUnit.assume()
.) (948f3edca)AssertionError
Truth generates as a substitute for ComparisonFailure
now includes the expected and actual values that were missing in 1.1.1. (6b0140730)Published by cpovirk over 3 years ago
We recommend not trying to exclude our JUnit dependency even under this release. We will release 1.1.2 with better handling for the missing dependency shortly.
Expect
, ExpectFailure
, and TruthJUnit.assume()
.) (2d65326ec)If you wish to exclude our JUnit dependency, you may wish to consider this alternative approach. That approach may be worthwhile even after we fix the bugs described above.
I apologize for the trouble.
Published by cpovirk almost 4 years ago
Error: com.android.tools.r8.errors.b: Compilation can't be completed because `org.objectweb.asm.ClassVisitor` and 1 other classes are missing.
(0bfa285fa)unpackingAnyUsing(TypeRegistry, ExtensionRegistry)
. If you call this method, ProtoTruth
will attempt to unpack Any
messages before comparing them. (b50d878b)formattingDiffsUsing
methods to IterableSubject
and MapSubject
. This allows you to get failure messages which show diffs between the actual and expected elements (like you get with comparingElementsUsing
) while still comparing them using object equality. (ae997be77)checker-qual
to qual
. (e71b57b9f) With this change, we inadvertently introduced Java 8 bytecode into our dependencies. Please report problems on #882. Sorry for the trouble.StringSubject
. (3481ab0af)<optional>
) by default. It is still safe to exclude if you want to minimize dependencies, but by including it, you may see better failure messages. (aea78e81c)gwt-user
. (b54e9ef50fe670bf93dd3b2b6851423be631b429)StringSubject
, visit truth.dev/StringSubject. Also, more easily access the index at truth.dev/api.Published by cpovirk almost 5 years ago
gwt-user
to test
scope. (51bbbf42)Published by cpovirk over 5 years ago
Truth is a library for performing assertions in tests:
assertThat(notificationText).contains("[email protected]");
Truth is owned and maintained by the Guava team. It is used in the majority of the tests in Google’s own codebase.
For more information, see our full documentation at truth.dev, or start with our higher-level blog post.
Users of AssertJ will be particularly interested in our comparison of Truth and AssertJ.
Truth 1.0 contains no changes relative to 1.0-rc2. For a list of changes since Truth 0.46, see the release notes for rc1 and rc2.
Now that we have reached 1.0 (after eight years! We're sorry, and we thank you again for your patience), we will maintain binary compatibility.
Published by cpovirk over 5 years ago
Sorry for the last-second changes. We still expect to release 1.0 on July 8.
DoubleSubject
and FloatSubject
to override isEqualTo
and isNotEqualTo
instead of declaring an overload. (4743c148)MultimapSubject.UsingCorrespondence
methods containsExactly
and containsAtLeast
to require an E
for their one non-varargs value argument, and removed their type parameters. (4743c148)MapSubject.UsingCorrespondence
and MultimapSubject.UsingCorrespondence
methods containsExactlyEntriesIn
and containsAtLeastEntriesIn
. (4743c148)IntStreamSubject
and LongStreamSubject
methods isInOrder
and isInStrictOrder
to require a compatible Comparator
. (4743c148)Published by cpovirk over 5 years ago
We expect to release 1.0 (and publish an official announcement) on Monday, July 8.
assertThat(0.0).isEqualTo(0)
pass, despite the mix of double
and int
. (And likewise for float
and int
.) This extends existing support that previously applied only to integral types. (1c5f9e8a)int
overloads of isGreaterThan
, isLessThan
, isAtLeast
, and isAtMost
. (dc92786f)StandardSubjectBuilder.fail(...)
that accepts a message. Instead of assert_().fail(...)
, use assertWithMessage(...).fail()
. Similarly, instead of expect.fail(...)
, use expect.withMessage(...).fail()
, and so forth. (f6875d6d)DefaultSubject
. Use plain Subject
. (f6875d6d)AtomicLongMapSubject
. In most cases, you can assert on the asMap()
view instead. (f6875d6d)Optional*Subject.hasValueThat()
. Instead of assertThat(optional).hasValueThat()....
, use assertThat(optional.getAs*())....
. (f6875d6d)Published by cpovirk over 5 years ago
containsAllOf
and containsAllIn
. Use containsAtLeast
and containsAtLeastElementsIn
, which are equivalent. (5de3d216)isOrdered
and isStrictlyOrdered
. Use isInOrder
and isInStrictOrder
, which are equivalent. (5de3d216)SortedMapSubject
and SortedSetSubject
. Users will have to perform assertions directly on the result of methods like firstKey
. We haven't found sufficient demand for the classes to keep them. (057ef315)ListMultimapSubject
, SetMultimapSubject
, and ProtoTruth equivalents, which add little to the general Multimap
subjects. (057ef315)Subject
. If you subclass this type (or declare it as a method return type, etc.), you will have to update those usages at the same time you update Truth. Or you can remove the type parameters from your usages (temporarily introducing rawtypes/unchecked warnings, which you may wish to suppress) and then update Truth (at which point the warnings will go away and you can remove any suppressions). (3740ee65) To remove the type parameters from Subject
subclasses, you can get most of the way there with a Perl-compatible regex search-and-replace operation: s/\bSubject<([^<>]*|[^<>]*<[^<>]*>[^<>]*|[^<>]*<[^<>]*>[^<>]*<[^<>]*>[^<>]*|[^<>]*<[^<>]*<[^<>]*>[^<>]*>)>/Subject/g
ComparableSubject
and most of the type parameters of IterableOfProtosSubject
, MapWithProtoValuesSubject
, and MultimapWithProtoValuesSubject
. If you subclass any of those types (or declare them as method return types, etc.), you will have to update those usages at the same time you update Truth. Or you can remove the type parameters from your usages, update Truth, and then add back the remaining type parameters. (e611568b)ProtoSubject
and LiteProtoSubject
. If you subclass either of those types (or declare them as method return types, etc.), you will have to update those usages at the same time you update Truth. Or you can remove the type parameters from your usages (temporarily introducing rawtypes/unchecked warnings, which you may wish to suppress) and then update Truth (at which point the warnings will go away and you can remove any suppressions). (eb3852c4)actual()
, getSubject()
, named()
, internalCustomName()
, and actualAsString()
. To automate most migrations, we've provided StoreActualValueInField
and NamedToWithMessage
(and a quick-and-dirty regex version for common cases). (If you are migrating manually, you may need to know how to handle java.util.Optional
, Stream
, and other types that aren't built in.) You might also be interested in our notes from the API Review of this decision. (c1db1b78)ProtoSubject
to not extend ProtoFluentAssertion
. It still contains all the same methods, except that isEqualTo
and isNotEqualTo
now require a Message
, rather than accept any Object
. (777af33d)StandardSubjectBuilder.fail(...)
that accepts a message. Instead of assert_().fail(...)
, use assertWithMessage(...).fail()
. Similarly, instead of expect.fail(...)
, use expect.withMessage(...).fail()
, and so forth. (227b559e)AtomicLongMapSubject
. In most cases, you can assert on the asMap()
view instead. (19e1f22c)Optional*Subject.hasValueThat()
. Instead of assertThat(optional).hasValueThat()....
, use assertThat(optional.getAs*())....
. (227b559e)assertWithMessage
to throw an exception if given format arguments but a null format string. (31e44cc3d2597b90986122853c149d68ea2c5cde)fail(...)
in terms of withMessage(...)
. This is mostly a no-op but can affect behavior in unusual cases. For details, see the commit description. (a52f89b9)IterableSubject.isEqualTo
produce the same message format as containsExactly
. (27a9111c504648ab830929730d6a2b0face5d23d)TruthFailureSubject.truthFailures()
factory for callers that want to test Truth failure messages with expect
, assertWithMessage
, etc. (c1db1b78)Published by cpovirk over 5 years ago
We are pushing hard to release a Truth 1.0 by June 30, after which we don't expect to remove any more APIs. Thanks for your patience with both our slow progress over the past several years and our rapid churn now.
To use the migration tools below, you'll need to set up Error Prone and configure our tools as plugins to run in patch mode.
Deletions:
Subject.isSameAs
and isNotSameAs
. Use isSameInstanceAs
and isNotSameInstanceAs
, which are equivalent. (36200e6a)Correspondence
. Use the class's static factory methods instead. The most mechanical migration is usually to Correspondence.from
. To help with migration, we're released CorrespondenceSubclassToFactoryCall
. (11da1ca2)Subject.fail*
methods. See Subject.failWithActual
and failWithoutActual
, which use the new Fact
class. To help with migration, we're released FailWithFacts
(and also ImplementAssertionWithChaining
, which is also sometimes useful for these migrations), though you will likely need to make manual changes, as well. (36200e6a)Subject.check()
. Use the overload that accepts a description. (To help with this migration, we have added ProvideDescriptionToCheck
to Error Prone -- but then removed it before it became part of a release, so you'll need to pull it in manually.) (36200e6a)MathUtil
. For similar static methods, see Guava's DoubleMath.fuzzyEquals
. But callers from custom Subject
implementations may prefer an approach like check("score()").that(actual.score()).isWithin(tolerance).of(expected)
. (7b2876d0)createAndEnableStackTrace()
. Use create()
, which now also enables stack traces. (9362f4cb)Deprecations:
isOrdered()
and isStrictlyOrdered()
. Use isInOrder()
and isInStrictOrder()
, which are equivalent. (146080a5, 386207d5)containsAll*
on ProtoTruth, *StreamSubject
, and Primitive*ArraySubject.*ArrayAsIterable
. Use containsAtLeast*
, which is equivalent. (82c1f2dc, 386207d5)Subject.actual()
. Instead of calling it, declare your own field to store the actual value. To automate most migrations, we've provided StoreActualValueInField
. (297c0f1e)Subject.named
. Instead of assertThat(foo).named("foo")
, use assertWithMessage("foo").that(foo)
. For custom subjects, use assertWithMessage("foo").about(foos()).that(foo)
. For other scenarios, see this FAQ entry about adding messages. To automate most migrations, we've provided NamedToWithMessage
(and a quick-and-dirty regex version for common cases). You might be interested in our notes from the API Review of this decision. (08afb24e)Subject
. To prepare for their removal in the next release, you can edit your code today to refer to the raw Subject
type. (Kotlin Subject
authors, see below.) Also "deprecated" the self-type parameter on ComparableSubject
. Again, you can prepare your code by referring to raw ComparableSubject
(and later change it to refer to ComparableSubject<T>
when the class has only one type parameter next release). Similarly, "deprecated" the type parameters on ProtoSubject
and LiteProtoSubject
, along with most of the type parameters of IterableOfProtosSubject
, MapWithProtoValuesSubject
, and MultimapWithProtoValuesSubject
. (21c29f77, 5abd9edc)Subject.Factory
. This permits custom Subject
subclasses extend raw Subject
instead of Subject<FooSubject, Foo>
to prepare for when we remove the type parameters from Subject
entirely.DefaultSubject
. Use plain Subject
. (7b5311b4)SortedMapSubject
and SortedSetSubject
. Users will have to perform assertions directly on the result of methods like firstKey
. We haven't found sufficient demand for the classes to keep them. (46aebcf4)SetMultimap
-specific and ListMultimap
-specific Subjects
, which add little to the general Multimap
subjects. (2103fee1)actualAsString()
and internalCustomName()
. They exist primarily to support named()
, which is being removed. (d69ba29f)Other migration notes:
actual()
and named()
before removing type parameters from custom Subject
classes.named
requires that custom Subject
classes expose a Subject.Factory
, as described in our docs about extensions.Subject
subclasses, you can get most of the way there with a Perl-compatible regex search-and-replace operation: s/\bSubject<([^<>]*|[^<>]*<[^<>]*>[^<>]*|[^<>]*<[^<>]*>[^<>]*<[^<>]*>[^<>]*|[^<>]*<[^<>]*<[^<>]*>[^<>]*>)>/Subject/g
Features:
assertThat(fetchLogMessages()).isEmpty()
might contain "value of: fetchLogMessages()." This feature is not available under Android or GWT, and it is only available if you have ASM on your classpath.ThrowableSubject
, MapSubject
, and MultimapSubject
to subclasses. Note that actually extending those subjects won't fully work until we remove the type parameters from Subject
. (1a39d5af, 32f76a59)DefaultSubject
extensible again. Kotlin subjects can now extend DefaultSubject
instead of Subject
. This lets those subjects compile both before and after we remove the type parameters from Subject
. After we remove the type parameters, Kotlin subjects should extend Subject
again (with no type parameters), as we'll later remove DefaultSubject
. (6e45b276)Subject
classes extend IterableSubject
, MapSubject
, and MultimapSubject
. (1a39d5af).Published by cpovirk over 5 years ago
To use the migration tools below, you'll need to set up Error Prone and configure our tools as plugins to run in patch mode.
Subject.isSameAs
and isNotSameAs
. Use isSameInstanceAs
and isNotSameInstanceAs
, which are equivalent. (bc845f0d)IterableSubject.containsAllOf
and containsAllIn
. Use the containsAtLeast
and containsAtLeastElementsIn
, which are equivalent. (bc845f0d)Subject.check()
. Use the overload that accepts a description. (To help with this migration, we have added ProvideDescriptionToCheck
to Error Prone -- but then removed it before it became part of a release, so you'll need to pull it in manually.) (bc845f0d)Expect.createAndEnableStackTrace()
. Expect.create()
now does the same thing. (bc845f0d)Correspondence
. Instead of extending the type, use its new static factories. To help with migration, we're released CorrespondenceSubclassToFactoryCall
. (bc845f0d, 8bd19b47)MathUtil
. For similar static methods, see Guava's DoubleMath.fuzzyEquals
. But callers from custom Subject
implementations may prefer an approach like check("score()").that(actual.score()).isWithin(tolerance).of(expected)
. (bc845f0d)ComparableSubject.comparesEqualTo
and Primitive{Double,Float}ArraySubject.hasValues{,Not}Within
. (cc796b34)ThrowableSubject.hasMessage()
(3164a248)Correspondence
instance that adds in diff-formatting behavior to an existing Correspondence
using Correspondence.formattingDiffsUsing
. (d2223603)Also note that the next version of Error Prone will include ImplementAssertionWithChaining
, which is sometimes useful for migrating off the deprecated Subject.fail*
methods.
Published by cpovirk over 5 years ago
com.google.guava:listenablefuture
. (45514882)containsAtLeast
and containsAtLeastEntriesIn
to MapSubject
and MultimapSubject
. (d44be00f)Subject.failWithRawMessage
. Its literal replacement is failWithoutActual(simpleFact(lenientFormat(message, parameters)))
, but most users will be able to find a shorter way to construct a better message, generally using failWithoutActual
. (97f822f2)Correspondence
instance using a lambda or method reference, with the Correspondence.from
factory method. (81ac47da)Correspondence
instance that transforms the actual elements using a lambda or method reference and tests for equality with the expected elements, with the Correspondence.transforming
factory method. (c60c71a2)Correspondence
instance that transforms the actual and expected elements using a lambda or method reference and tests for equality, with the Correspondence.transforming
factory method. (780ecc2d)IterableSubject.UsingCorrespondence.displayingDiffsPairedBy
for details). (a675e321)Correspondence.formatDiff
(see the javadoc of that method for details). (5006a52a)Correspondence.compare
(see the javadoc of that method for details). (a474ac14)Published by cpovirk over 6 years ago
<provided>
. See https://github.com/google/guava/issues/2721 for details, but in short, feel free to exclude them if that works for your setup.NPE
in MapSubject.containsExactly
(https://github.com/google/truth/issues/468).