-
-
Notifications
You must be signed in to change notification settings - Fork 702
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
Flawed tests that pass instead of alerting user of an issue #726
Comments
If this project was new, I'd feel like replacing all property assertions with method assertions would be the obvious correct choice. But given the maturity of Chai, I'm worried about how extreme of a breaking change it is. I'm currently undecided. If we do go with this approach, I'd say that it should not only be released in a new major version, but that it should be the only change introduced in the entire major version, both to make it easier for consumers to pick which version they want to use based on this one specific change, as well as to make it easier for consumers to update their code without having to worry about more than one change at a time. Although they're not mutually exclusive, I'm only in favor of using ES6 Proxy to detect invalid assertions if we don't replace all property assertions with method assertions. It feels pretty cool and didn't end up being nearly as complex as I feared, but I'm a bit uncomfortable with having the code path be different based on the JavaScript version. Still, I think Problem A is a big enough problem that if we don't fix it by replacing all property assertions with method assertions, then we should fix it with ES6 proxy. I don't think Problem B is nearly as prevalent, so I'm not particularly concerned that this approach doesn't address it. As for adding a mechanism to verify that the expected number of assertions were run in each test... I think this has a lot of potential as a cool feature, but will be difficult to do correctly as explained in my first post. I'm in favor of eventually working something like this into Chai core regardless of what we do with property assertions and ES6 Proxy. After all, it addresses one of the problems that neither of the other two approaches does. In conclusion, I'm in favor of either replacing all property assertions with method assertions, or using ES6 Proxy to detect invalid assertions, but not both. Not sure which I prefer yet. Regardless, I'm also in favor of eventually adding a mechanism to verify that the expected number of assertions were run in each test, but I consider this a longer term addition. Edit: One of the biggest advantages of replacing all property assertions with method assertions is that it allows consumers to use a linting tool to catch invalid assertions. But it's possible for a linting tool to provide that service anyway, without replacing property assertions. A custom ESLint plugin for Chai would likely be the best solution. Looks like there's already one in the works: eslint-plugin-chai-expect. |
I think I'd like to get rid of property assertions - they have many different types of bugs, from odd stack traces, to confusing developers (both plugin developers and users writing tests). Also in the roadmap issue I briefly mentioned some of the impact these property assertions have:
I think we can mitigate the pain of removing them by spreading the changes over several major versions, a loose plan would be:
|
I'm on board for removing property assertions, and following a gradual approach in doing so, but in that case I think we should consider implementing the proxy stuff in the short term (even though that contradicts what I said earlier about not doing both). I think it'll be a decent chunk of time until #585 is in place, whereas I consider Problem A in my original post fairly urgent. |
Ultimately I think all 3 solutions could be used. We've definitely had requests for counting assertions before (not necessarily because of property assertions though). But yes I agree, proxies will solve problems the quickest with (hopefully) the least impact. |
+1 I was about to open the same issue right now. All the proposed solutions would work great for me. |
We did this before, around Chai 1.10.0. It didn't end well, because it causes all kinds of issues with chaining of assertions. You can read the full story here: #371 (comment). Here's the release notes for Chai 2.0 which removed this: https://github.com/chaijs/chai/releases/tag/2.0.0 |
What kinds of issues? If, instead of a noop, the assertion simply returns itself when called, wouldn't that cover those kinds of issues? If a proxy were used to check if an assertion is callable in the {{apply()}} trap (returning the assertion itself if not callable), perhaps it would be possible to "fix" existing plugins while at the same time retaining compatibility. Property assertions frustrated me to the point of enforcing stricter linting rules for work projects, as several tests were passing when they should have failed due to typos or incorrect assumptions about the assertions available. |
@andyearnshaw The good news is, starting with Chai 4.x.x, an error will be thrown when an invalid property assertion is used (due to type or incorrect assumption). See: #721 The best place to read about the issues with the previous attempt at allowing both property and method assertions is: #302, particularly #302 (comment) I think one could make an argument that it's worth supporting both property and method assertions if the only thing that breaks is assertions such as I'm not sure the idea you've proposed with proxies is viable. My understanding is that the Apply trap will only work if the thing being proxied is a function. In other words, it can't be used as a mechanism to detect if something that's being called is actually callable. Please correct me though if I'm misunderstanding your idea (or if I have incorrect knowledge of the proxy Apply trap). |
@meeber: ah yes, it looks like you're correct. I recall an early implementation in Chrome allowed this, but now that I've checked the spec I can see that it's wrong. Glad to see the throw for invalid property assertions coming in 4.x.x, that might change my mind about them! |
Here's a trap I just fell in. Sorry if you're already aware of it.
This looks correct and makes intuitive sense, at least to me as a newcomer, but doesn't test anything. |
Hi @tristanisme, thanks for your report! However, your syntax consideration seems common and natural enough for me to think it should be considered correct. IMO this behavior should be added to Chai's core. Perhaps we could make equal have a different behavior by defining its If we really wanted to do this I think it would only be a matter of using I'd like to hear @keithamus and @meeber opinions on this one, what do you guys think? |
Proxies should solve this, come As for supporting those, IMO I'd rather steer away from property assertions than into them. |
@keithamus I just tested here using the 4.x.x branch and I don't think that Proxies would solve this case. What I did to test this was: Please correct me if I'm wrong or if my method for testing this is wrong. |
@vieiralucas we're in a bit of a mixed state right now. I have a vague feeling that Proxies might be in the |
@lucasfcosta and @vieiralucas are correct that proxies won't catch this particular problem. Since the |
It's also worth mentioning that something like |
We can use proxies to wrap functions so we can mirror the same behaviour that we have with objects now, on the functions. |
@keithamus Great idea. In fact, I wonder if an attempt to access any property on a non-chainable method assertion should throw an error, even if the property exists. For example |
Great idea by @keithamus, +1 for that! |
The release of Chai v4 with proxy protection drastically mitigated this problem. Gonna close. |
We have a problem in Chai. The problem is that it's too easy to write tests that appear valid but are actually broken in such a way that they pass no matter what. Strict TDD/BDD can help mitigate this problem, but it's not enough, especially when reviewing PRs from developers of varying skill levels.
Before discussing solutions, it's important to understand the different ways this problem can manifest. Here are three:
Commonly proposed solutions include:
None of these solutions are mutually exclusive. Here are some pros and cons of each approach:
Replace all property assertions with method assertions
Pros:
Cons:
Use ES6 Proxy to detect invalid assertions
Pros:
Cons:
Add a mechanism to verify that the expected number of assertions were run in each test
Pros:
Cons:
Note: A variation of this approach is to merely verify that at least one assertion was run in each test, instead of a specific number, which would be potentially easier for Chai to implement and developers to use, but would mean that it no longer completely fixes any of the problems, only decreases the likelihood of them occurring.
The text was updated successfully, but these errors were encountered: