Thoughts on testing with Chai

As I was doing the final Quality Assurance Project one thought crossed my mind.

Testing with Chai is not particularly hard for me, and while it doesn’t seem extremely valuable to me at the moment due to the relative simplicity of the projects, I am guessing, that testing will become more and more useful as projects get more and more complex.

So with regards to that:

Which one of the two is better/more useful? Is there even a clear answer to this?

// #1
assert.equal(exampleText, "Is a string")

// #2
assert.isString(exampleText)
assert.equal(exampleText, "Is a string")

Or in other words, is it better to test for more, or is it better to make more compact tests?

Edit: The specific reason why I’m asking is, that I don’t really know sometimes what exactly to test for. If I see that my application basically works as I want it too, I mostly just write extremely simple tests, like in the first example.

Curious to hear some thoughts on this.

Hello there,

Definitely not #1. If you are wanting to assert that a variable is a string, then use isString. There is no need for equal, in the above.

Let me start with this: I have yet to see a codebase which tests enough.

Otherwise, it is only useful to have a lot of tests if they each contribute something useful/unique to the problem. Referring back to your #2, you can see why it might just be annoying to have two tests checking if something is a string, especially when one of them is not testing in an expected way.

A better example of more tests for the sake of easier to understand failures would be:

assert.isString(someVar);
assert.equal(someVar, "1234", "'someVar' is not the expected value");
// Personally, I would use `strictEqual` here

The point of the above is when something in the codebase changes, and someVar accidentally becomes:

  • Not a string
  • Not equal to "1234"

The output of the assertion will be detailed enough to easily debug what has gone wrong.


Tests are not meant to help you develop an application (most of the time). They help you once you have developed, and start adding/making changes, and you want to ensure all aspects of the software still work as expected.

So, if something is likely to change, add a test for it.

The times this has helped me the most is when I am working with complex shapes (lots of data), and I need to make sure the same shape of data is always sent to the correct places, and if I (make a change)/(introduce a new source of data), the areas of the software I am not (thinking about)/(tinkering with) are not affected.

I hope this helps some

1 Like

I’m guessing people that do pure TDD would disagree here. Some do actually start with the tests and then write code to pass the tests, not the other way around. But yes, tests will most definitely also catch errors when refactoring or extending code.


Obviously, the larger and more complex the code base is and the more people that work on it the more useful testing becomes. Sort of like how TypeScript becomes exponentially more useful the larger the app and team are.

But testing is a huge subject and I’m not at all an expert. So I won’t really attempt to give any suggestions. Unless I’m required to write a test, I likely won’t. But then again, I’m not writing massive apps with lots of money on the line.

1 Like

Thanks for the answer, it does provide some clarity on the utility of tests.

I am not sure wether I understand your point regarding #1 correctly, or wether I have perhaps chosen a poor example.

What I meant is this:

let example = "This text could change but it I expect it to remain a string"

function(example) {
  //something that could change example (and to be precise, of course strings are 
  //immutable, so something that could reassign example to another string)
  return
}


// and now either

//#1 
assert.equal(example, "This text could change but it I expect it to remain a string")

//or

//#2
assert.isString(example)
assert.equal(example, "This text could change but it I expect it to remain a string")

So to reference:

Is this a good rule of thumb?
Would #1 be a better way to test in this case, since the fact, that example is a string is unlikely to change?

If you just need to assert a value, I’m not sure how useful a type check is. It can’t really change type and not fail the value assert.

However, you might have instances where you need to check the type before you can reliably test the value (maybe not in your example).

1 Like

Good point. I suppose I have no experience with that, but I have never heard of anyone starting with tests - there has to be boilerplate code to begin with, then tests are written. That is, the tests do not work without the scaffolding, and need to be based around that scaffold.


@michaelmanke00

It is my rule of thumb…gets me going with writing tests, if anything.

The issue I have with the example is that it is not checking whether something is a string. Remember, assert.equal("Some string", "Original string") returns false. Having a test for something like that is unlikely to be useful. The only time I have ever had anything similar is I have a test checking if I correctly set my environment back to "production", after changing it to "development", before deployment.

At the end of the day, it is up to the specifics of the problem, which tests make the most sense. If you want more information (is something a string, and is it always a specific value), then write more tests so the assertions can tell you “Hey, this failed because it is not equal, but it is still a string”.

1 Like

Perfect, adds a lot of clarity! Thanks for the responses.

The tests are supposed to start out failing and the code you write makes them pass. You do not write code, then write tests that pass the code, it’s the other way around. So, requirements → tests → code. That is the normal TDD red → green approach as far as I know. But I’m no TDD expert.

That is BTW also how the fCC curriculum works. All (or most) tests should be failing by default because no code have been written yet. That approach is not special to the curriculum, it’s pretty much just TDD.

Thank you, for the clarification. This is a decent example.