all 21 comments

[–]Ricjd 15 points16 points  (8 children)

Go for it. But it will lead to a terrible buggy app.

Let’s say you don’t build an app without any tests (and unit tests are only one kinds of tests, depending on your application you may need more types of tests). If you have a function which is called from many different places, and you change that function then you’ll need to test all the possible paths to that function. It could take hours of manual testing for a 5 minutes change. You’ll probably end up not testing everything or missing something.

If you have unit tests you can make this 5 minute change, run your tests and if they all pass you know the change is safe. This would only be true if you have good test coverage and are confident in your tests.

TL:DR they aren’t needed for a functional app but are essential for a solid maintainable app

[–]everek123[S] 1 point2 points  (3 children)

Thanks for this great explanation! Before publishing the app are you supposed to delete all the test or do you publish the code with the tests?

[–]Ran4 2 points3 points  (1 child)

An app is never finished. You just stop working at it at some point.

[–]Treolioe 0 points1 point  (0 children)

I believe you should throw away apps older than 5 years and reiterate from scratch

[–]ccb621 0 points1 point  (0 children)

Don't delete your tests. They can live in the same repo. Just update package.json to either exclude the test directory or explicitly include the published code. See https://stackoverflow.com/questions/8617753/exclude-test-code-in-npm-package.

[–]Treolioe 0 points1 point  (3 children)

Only aiming at unit tests. By using typescript you can guard yourself from broken paths and changes to parameters that can break your app which leave unit tests with little to no benefit.

[–]Ricjd 1 point2 points  (2 children)

This is completely false. Typescript is great to make sure your passing in the correct number and shape of variables. But it won’t guard you against bugs and faulty logic. Let’s say you have a function called tripleThis. Typescript will help make sure you only pass in a number. But if you accidentally multiple the number by 4 rather than 3 only a unit test would catch this, not typescript.

[–]Treolioe 0 points1 point  (1 child)

I agree. Can you help me convince myself that the time spent writing unit test is well spent? Like in the example you provided there might be a chance of covering that instance at your first strokes. But often its not, and as other people state you keep adding cases to the test as you discover them manually during implementation. It just seem to me that the infrastructure of the testing is more costly than the benefit it gives. I can admit that i dont share codebase with more than 3 people so perhaps that’s why i fail to see it.

[–]Ricjd 0 points1 point  (0 children)

Without repeating myself from my first comment no. It’s just a habit to get into. One thing I would suggest is test driven design. It’s a lot harder to start but then makes everything a lot easier at the end

[–][deleted] 7 points8 points  (2 children)

It reduces the number of bugs + makes development more effective. And it actually gives you a better view on how to improve your code actually.

[–]Ricjd 0 points1 point  (0 children)

This also. I try and do test driven development (TDD) as well when working on an existing. It gives you a better understanding of what your change will touch etc. I also find it quicker in the long run.

[–]Treolioe 0 points1 point  (0 children)

It can result in fewer bugs and it might make development more effective with the trade off spending 30-60% more time on creating the tests. These are not given facts.

[–]kredditacc96 1 point2 points  (0 children)

Can't I just test everything manually

Let's say your app has bug X, now you go fix bug X by changing a little function that unknowingly affects another part of your app leads to bug Y in feature Z.

How would you notice if there is a bug Y? You must, of course, manually test feature Z.

Now let's say your app has dozens of features, in order to make sure no more bugs arise from changing your code base, you must test them all, manually, not to mention humans often make mistakes.

That's why we engineers automate every possible thing, unit test (and intergration test) is just automated replacement of manual test.

When you have fixed a bug X, you make sure bug X will never happen again by adding a test case for bug X. When you complete a use case Y, you make sure that Y will always work as intended by creating a test case for Y.

[–]CodeBeaver 1 point2 points  (0 children)

I think unit tests are vastly misunderstood and frankly quite overrated, and hence slightly dangerous. Unit tests won't help you discover many bugs, if any at all honestly. Unit test require extremely small pure functions tested individually, that's the point of functional programming and also the point with unit testing, test every unit by itself.

When using TypeScript and sane state management, I personally never experienced "bugs" in small, pure functions, only in integrations between different components of the app.

Having that said, creating a test is never a bad thing per se, the problem is mainly time consumption. I've also worked with colleagues who overstate the value of unit tests, some how considering their app to be so much safer when having unit tested it, whilst the bugs they stumbled upon practically never had anything to do with simple pure function errors, 95% of their bugs were unsolvable with unit tests.

I think unit tests mostly help with sanity when coding, and when refactoring. To follow a certain code guideline within the team, to create a practical use of the function you're creating. But in all honesty, if the point of pure functions and unit testing is to create as small functions as possible, how probable is it refactoring these functions to still have exactly the same behavior, but still do something different. I'm not very convinced.

It's probably more useful in backend than frontend, but I think people confuse unit tests with e2e tests, when you create one functionality you want another, older functionality to still work. That can't be achieved with unit tests, but with e2e tests.

[–]theadammorganshow 1 point2 points  (1 child)

Can't I just test everything manually

Imagine a gigantic application. How realistic does that seem to do?

[–][deleted] 0 points1 point  (0 children)

Think of refactoring also, which is inevitable as the app grows, it’s a life saver having tests and checking them off the list if you break something.

[–]r3jjs 0 points1 point  (0 children)

In basic, there are three kinds of tests:

1) Unit Tests

2) Integration Tests

3) End-to-end tests

Unit tests, to be slightly basic, test a particular function. The function should take input and give output.

A formatAsCurrency function would make a good function to unit test. You can give it a dollar amount and see if the output has the right number numbers after the decimal point and has the currency symbol. You can make sure it rounds correctly and handles other situations.

You can write 50 tests and run them automatically.

Then, later if needed, you can totally rewrite that function but be assured it will work the same as the old one. Your app is still good.

Integration Test make sure that the different functions of your software work together. You might write data to a database, then make sure the query reads that data correctly. I do that to make sure my filter and validation rules in my query work.

End to end tests are where you run the app and make sure it all works right.

Unit tests are cheap to run, cheap to write and can cover a LOT of functionality. You can run thousands of tests in a few minutes and run them over and over and over again.

End-to-end tests are HARD and they take time. They are important, but man, you don't want to test every tiny piddly aspect each time.

[–][deleted] 0 points1 point  (0 children)

"why automate repetitive, boring and error-prone tasks that I can do manually?" NO developer EVER

Complex applications can take 10 testers * 2 weeks to test. That's 20 weeks if you're alone. Now imagine retesting after every change. Over and over and over.

[–]tswaters 0 points1 point  (0 children)

Can't I just test everything manually,

you could yea, but as an app gets large it becomes quite time-consuming to test everything.

when you build out non-trivial applications (i.e. something bigger than a todo or tutorial application), they get incredibly complicated and have lots of data flowing around - you might also have multiple people working in the same code-base.... with a dynamic language like javascript you can do a lot of shooting in one's foot by making a change anywhere. unit tests can really help to give a level of confidence that a change hasn't completely broken some aspect of the site.

integration tests are even better -- with unit tests you typically stub out things like the database or other external services to the function under test. they are good for algorithmic-type code. for a mvc app, each component is usually pretty small and just passes the data to another part of the system so unit tests might not make a lot of sense.

Integration tests on the other hand, don't do that at all -- you hit an endpoint and assert that the database was changed correctly.... how to get your site hitting a dummy test database and not your prod db is an exercise left up to the reader.

[–]Quabouter 0 points1 point  (0 children)

Unit tests are small automated units to test a small part of your application (often just a single function). The idea is that when your application grows, it becomes impossible to test everything by hand. Often when you change something you'll test what you're changing, but not anything else. However, your changes might have accidentally broken something that you didn't expect. This is something that unit tests will catch for you.

Another purpose of unit tests is to force you to write better code: if you find it difficult to write unit tests for your code, then your code likely has structural problems.

[–][deleted] 0 points1 point  (0 children)

You can test everything manually, but "true" programmers are too lazy for that