Kinds of Testing
Every test in this chapter has been a unit test.
A unit test exercises one small unit of code, separately from the rest of the program. For us, that unit is a single operation of the ADT. Each @Test method checks one behavior of one operation, on a fresh list. From here on, the accompanying code for each chapter will include unit tests for the data structures you build.
We also tested in a particular way. None of our tests reached inside the class to inspect the backing array of the ArrayList or the nodes of the LinkedList. They only called the public operations and tested the specified behavior of the ADT. Testing a class this way, without looking at its internal structure, is called black-box testing.
The opposite is white-box testing. There you do look inside, and you base your tests on the internal structure of the implementation. You write tests that take each branch, hit each loop boundary, and run each path at least once.
Integration testing checks that several units work together correctly. Testing the operations of a single class is unit testing. Testing that the class works correctly when it is used by another class or when it is part of a larger system is integration testing.
End-to-end testing is when you run the whole program and check that it behaves correctly. It is a kind of integration testing that exercises the whole program from the outside, the way a real user would.
Regression testing is not really a different kind of test. It is a different reason for running the tests you already have. It means re-running your existing suite after every change, to catch anything you broke without noticing.
There are other kinds of testing too, such as performance tests, load tests, and property-based tests.