-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Truth Subject#check #1092
Comments
Thanks for the report. On this part:
I didn't quite get the connection to nullability for this example? Conceptually, adding the requested support is not difficult. It's just a bit of a pain to implement. We can look into it, though I think we have higher-priority issues to deal with at the moment. |
Thanks, it’s not much of an issue. I think only once or twice, but maybe in a larger code base it will be desirable. I’d backlog until others ask for it, or close as informational. The last was merely an example for why custom assertions is nice and unrelated. Most developers don’t realize they can do this or that it’s the intended usage of the assertion library. I wanted to show that in case it came across as an obscure use-case. |
From the perspective of Truth, recognizing For what it's worth, I generally discourage running nullness checking on tests, since the cost of NPE there is generally lower, though I do see some advantages to it, and I'd be interested in thoughts from either of you, given that you may have given it more thought than I have. One other note on |
I agree that I typically wouldn't enable this for tests given the low maintainability benefit to noise ratio. In this case, since some assertion support exists, extending it slightly could be nice for those rarer cases where it is enabled (but as a lowest priority ticket). Caffeine seems popular at 250M Maven Central downloads in 2024 and, though I lack a comparison metric and believe it is mostly uncached CI runs, that is high enough to deserve extra care. Therefore, I went through the exercise of enabling all of the static analyzers as a low effort approach that might unearth bugs and thankfully only found mistakes in test logic that reduced coverage. That reasoning also led me to try to maximize line coverage (99% is certainly ridiculous) which did uncover edge cases. I've found bugs each time that I try to tighten up lax testing practices, such as when covering all cases when a callback may fail (review led to a fix). Fuzz testing the spec parser found minor bugs and thankfully linearization model checking only found bugs in the tool itself. I also ported other collection library test suites (jsr, apache, eclipse, guava) in case other developers thought of a scenario that I didn't consider. Most importantly for my own sanity, at the start I knew that the mental complexity was far too high for me to reliably implement the library or make changes. I took the unorthodox approach of brute forcing the test suite to cover all configurations and that avoided countless bugs. Similarly, the cache simulator as a test analysis tool was a necessity to explore algorithmic ideas and have a simpler reference to verify against to avoid hit rate regressions. This is all a long winded way to say that the library pushed well past my abilities so I happily use every possible scheme to make up for my shortcomings. And, given that I rarely get to write much code anymore, its a nice way to decompress with low mental effort that keeps improving the code quality. For the average code base all of this is masochistic and developers should find their own happy balance so your general discouragement is correct. |
I can see things both ways (and this is based only on a limited amount of personal experience). If your whole code base is run under a nullness checker, and you can assume client code will be also, I can see value in running the nullness checker on tests as an extra check on your nullness types. E.g., you might write a function that accepts On the other hand, if you're writing a library where clients may not be nullness checked (like Caffeine), you might be adding defensive null checks in your functions, even for As the Java ecosystem moves toward more and more nullness checking, I expect it will make more and more sense to run nullness checking on tests. And this makes sense in a way: for a language like Kotlin that bakes in nullness type checking, by default the checking runs on your test code as well. PS:
@ben-manes just curious where do you see these stats? |
oss.sonatype.org provides statistics privately to the artifact owner, although half the time this dashboard is broken and fails to load. It retains a 12 months history, offers no comparisons wrt popularity, and the only user analysis is unique IPs (perhaps is meaningless in cloud CI). I downloaded the csv export, taking Dec 2023 instead of projecting, which sums to 250,327,009. It is a feel good number like github stars, likely meaningless but also kind of neat. I have no idea about more popular libraries, like Guava, though JUnit recently posted ~50M/month for v5 (122M across major versions). |
The test assertion library support will infer from an
assertThat
statement for use in a test method. A more advanced user may want to write custom assertions, known as aSubject
, in order to create their own reusable ones. This internally uses thecheck
method to use the nicely formatted error messaging subsystem. Currently NullAway does not understand this for reasoning about the possibility of null dereferences.In this example the
check("value").that(value).isNotNull()
precedes thecheck...containsValue(value)
and emits a warning thatcontainsValue
requires a non-null parameter.The benefit is that test methods can continue to stay focused on the behavioral aspects instead of having repeated logic that inspects implementation details. For example inspecting the listener configured on the cache so ensure the correct events were emited.
Another scenario to support is
assertWithMessage(msg).that(subject).isNotNull()
. This is anassertThat
where the message can be supplied for a better description.I've also had cases where the null assertion was not taken into account and it warns about the following statement. I believe this is because I have my own
FutureSubject
andMethodNameUtil
looks for concrete classes rather than at the polymorphic type.The text was updated successfully, but these errors were encountered: