I found this example of Smoke Test with ReactJS and Jest, but I can’t understand it. Someone can explain it to me, please?
Well, first I can’t see the difference between ‘smoke tests’ and ‘unit tests’ I see people say smoke tests are superficial and obvious. But every unit test isn’t it? I mean, every one of them isn’t made to check if things are working the way they should work? When a test isn’t obvious and can be understanded not as a "smoke test", but as a "unit test"? Second, I’m starting with unit tests and I can’t understand Jest mechanism. In this case, it creates a div trough "document.Element(‘div’)" and then compare with my project div, "MyCard"?
Thanks in advance.
// MyCard.js
import React from "react";
const MyCard = () => {
const [counter, setCounter] = React.useState(0);
const handleClick = () => {
setCounter(counter++);
}
return (
<div>
<p>Counter: {counter}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}
export default MyCard;
//MyCard.test.js
import React from "react";
import ReactDOM from "react-dom";
import MyCard from "./MyCard";
it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<MyCard />, div);
});
I tried the example, it worked. But I can’t understand why.
2
Answers
Why wouldn’t it work? It’s testing that the component just does something; quoting Wikipedia on smoke tests,
In this case, the test addresses the question "does it render at all".
So based on your comment there are two components to this question. What makes a smoke test different to a unit test? and What is this smoke test doing, and why?
A unit test has a very limited scope. A proper unit test will cover a single unit of a larger system. Compare that to, for example, an integration test or an end-to-end test which have a larger scope. Good, thorough unit tests will also cover all relevant aspects of the module they are testing, which can mean testing every line and every conditional. Writing and running a full suite of unit tests can verify a lot about the behaviour of your code, but it’s possible to have a broken program in which every unit test passes, due to some of the integrations being broken, for example.
A smoke test, instead, is a low-effort sanity check to make sure that something works. It doesn’t guarantee that it works well, or that there are no bugs, or that the behaviour or appearance are correct, just that that aspect of the system hasn’t been completely broken. Smoke tests are less powerful than a full suite of tests but they tend to be faster to write, easier to update if the code is refactored or changed, and much better than no automated testing at all.
It can be useful to look at what would cause a smoke test to fail, in order to understand why it’s useful. In this case the test is creating an empty element, then adding our custom component as a child element. The test passes as long as we are able to do this without
ReactDOM.render()
throwing an error. So when would this fail? Simply put, this fails if our element has invalid syntax. Let’s say we accidentally delete the closing tag in the HTML – this would throw an error, the smoke test would fail, and we would know that the component needs looking at.Is it as thorough as a proper set of unit tests where we check that the counter works as expected? No. At the same time, though, this is a very fast test to write, and even if we have other unit tests it can be good for debugging to know whether this test passes or fails. If we add another unit test that checks whether the counter is working, and that test fails but this one passes, we know the counter is broken. However if this test fails too, we know that the counter isn’t the problem, it’s the whole component.