Unit testing is just one of the multiple types of testing. Basically, you'll find three types of tests:
Each of those tests ensure that a tiny piece of application is working as expected. For example, a unit test will ensure that if, on an e-commerce website, I create an instance of a
Product class with a price inferior to zero, an exception will be thrown.
This is similar to unit tests, but with a larger scope. Once you created the blocks of the application and test them, you start to assemble them into something bigger. Integration tests ensure that those blocks work as expected when assembled.
For example, your product management block was unit tested to prevent creating products with a price inferior to zero, and your administrative interface block was tested to prevent invalid values from being entered by the users, but what about those two blocks interacting one with another?
The scope of those tests is even larger. While integration tests are more concerned with interfaces between two blocks, system tests are run on the whole system.
For example, what happens when two administrators attempt to modify the product with the same ID, while the primary database goes down for a few seconds, letting the mirror database to handle the operation?
To complicate things a bit, there are additional types of testing, such as:
While the earlier tests are often conducted by developers themselves, functional tests are usually done by QA department to ensure that the product corresponds to the requirements. While unit, integration and system tests are focused on the actual blocks and their interaction, functional tests are focused on requirements, which means that they treat the application as a black box.
For example, if a requirement specifies that the product cannot be purchased more than once per ten seconds by the same user, the test would consist of ordering the product twice in a period of ten seconds and check that the second order failed. Here, the QA tester doesn't care about how the functionality is implemented and what parts of the app are interacting to prevent the frequent purchase.
There is also security testing, A/B testing, regression testing, acceptance testing, non-functional testing, etc., but let's focus on system and functional tests above.
A functional test such as:
- Ensure credit card information is remembered by the website.
- Go to the product 123.
- Add it to cart.
- Go to cart.
- Make the one-click purchase.
- Repeat steps 2 to 5, given that the entire test should take less than ten seconds.
Ensure the last step fails and the user is informed that:
- The purchase was not made because there is a risk of mistake from the user,
- The IP address was saved in case of abuse,
- The e-mail was sent to inform the user about the risk of abuse,
- The credit card was not debited.
- Impossible to make by hand (unless you have a really fast tester),
- Is just too painful to do by hand anyway (especially in a context of Continuous Integration, where it may need to be done dozens of times per day, among several thousand of other tests),
- Is quite difficult to implement using "ordinary" programming, such as a bunch of HTTP requests and responses checking,
- Would be unmaintainable if implemented using "ordinary" programming.
This is when Selenium is useful. You create your scenario, and Selenium runs it again and again, checking that the test still passes. A similar scenario concerns system testing; although I don't expect Selenium to be very present here, it's not excluded that some teams rely on Selenium for this sort of testing.
If your project has requirements, a bunch of Selenium tests will be organized around those requirements, like in the example in my answer.
If not, each of those tests will just be a possible scenario which could get terribly wrong, similarly to what you do when choosing what unit tests to create. Just like in unit tests, you will test some method for input value
3 (ordinary case),
0 (edge case),
-1 (exceptional case) and
NaN (exceptional case), Selenium tests can encompass very diverse situations, such as:
The user purchases a product. That's all.
This is also probably the most crucial test one can have for an e-commerce website: if users can't purchase, it would be slightly problematic.
The user adds a product to the cart, waits until the product is not available any longer, and then tries to purchase it.
The user adds a product, then removes it, then presses Back, and tries to purchase.
The user bruteforces the website by adding every available product with maximum quantities in the shortest possible amount of time, and tries to purchase that.
The user starts purchasing a product, but leaves when the transaction is running, and never returns.