+++ description = "TDD, Chrome DevTools, error tracking" title = "Testing & Debugging" draft = false weight = 200 bref="Software testing is an investigation conducted to provide stakeholders with information about the quality of the software product or service under test. Debugging is the process of finding and resolving defects or problems within a computer program that prevent correct operation of computer software or a system" toc = true script = 'animation' +++
TDD is a design process, not a testing process. TDD is a robust way of designing software components ("units") interactively so that their behaviour is specified through unit tests.
How? Why?
- Write a simple failing test
- Make the test pass by writing the minimum amount of code
- Refactor the code by applying design principles/patterns
During phase 2, don't bother with quality.
- Writing a test first makes the code design more testable
- Writing just the amount of code needed to implement the required functionality makes the resulting codebase minimal, thus more maintainable
- The codebase can be enhanced using refactoring mechanisms, the tests give you confidence that the new code is not modifying the existing functionalities
- Cleaning the code in each cycle makes the codebase more maintainable, it is much cheaper to change the code frequently and in small increments
- Fast feedback for the developers, you know that you don't break anything and that you are evolving the system in a good direction
- Generates confidence to add features, fix bugs, or explore new designs
Note that code written without a test-first approach is often very hard to test!
- Unit testing
- Individual units/components of a software are tested. A unit is the smallest testable part of any software. It usually has one or a few inputs and usually a single output.
- Integration testing
- Individual software modules are combined and tested as a group.
- System testing
- A complete and integrated software is tested for compliance with the specified requirements.
- Acceptance testing
- A system is tested for acceptability and ready for delivery.
- A curated list of articles related to JavaScript testing
- Going over from everything from testing libraries, best practices, tips & tricks, and more.
The V-model of software development identifies testing tasks for each stage of development.
- Types of errors
-
- Syntax or interpretation errors - These include mismatched or missing quotes, parentheses and braces, incorrect case, spelling mistakes, illegal characters, and more. These erros can usually be caught using linters like ESlint or JSLint. Linters analyze your code before it is executed and point out syntax and other common errors.
- Runtime exceptions - These are the errors that occur when your JavaScript code executes. Such errors can be triggered by referring to an undefined variable, dividing by zero, by a failed “assert” statement, or by using a “throw” statement in your (or a JavaScript library’s) code to manually specify that an exception has occurred. When a runtime exception occurs, any JavaScript code after that line of code is not executed so they can leave your web page or application in an unexpected state. You can catch and handle runtime exceptions by wrapping the code that fails with a try {code} catch(exception) {} block.
- Incorrect logic - does not show any errors but causes your code to not do what you intend it to. Debugging such errors requires some practice using debugging tools that your browser provides.
- Chrome DevTools
-
- Console - Use console.log() to dump statements and other useful information like stack variables. Use console.assert() to ensure that certain conditions or assumptions are being met in your code. This also dumps the execution call stack and continues execution after the assert.
- Debugger - To specify a breakpoint, click on its line number in your code editor or in the Sources panel in Chrome DevTools. This will cause the debugger to pause at that line and allow you to inspect variables, the call stack, and evaluate expressions. With the debugger you can continue execution by stepping over the code line-by-line. You can set watches for variables and see how they change as you step over the code line by line. DevTools also has conditional breakpoints where you can specify the condition when the debugger stops execution.
- Working with APIs - The Networks panel in DevTools shows you, for each network request, the “method” (e.g. GET, POST), the HTTP status code (e.g. 200, 403), the MIMEtype (e.g. application/json), the content’s size and whether the network request was fulfilled from the browser’s cache.
- Tips - To ensure that your web page is using the latest version of your code, disable the browser cache in the DevTools settings. Also, when inspecting JavaScript objects, remember to use console.log(JSON.parse(JSON.stringify(obj)));.
- Official Documentation
- Error tracking
- Logging - the practice of storing large volumes of computer generated audit logs for later analysis. The creation of logs is dependent on the goals of the application. In addition, there are middleware packages like Morgan that can automate some of these processes. For reporting, modern logging systems use Elasticsearch to visualize logs and metrics using string analysis.
Logging can also be used for:- Compliance with security policies
- Compliance with audit or regulation
- System troubleshooting
- Forensics (during investigations or in response to subpoena)
- Security incident response
- Understanding online user behavior
- Monitoring
- It is important to monitor systems and send automated notifications to respond to system-wide performance changes. On AWS, CloudWatch provides a unified view of AWS resources, applications and services that run on AWS. You can set alarms, visualize logs and metrics, take automated actions, configure health checks, troubleshoot issues, and discover insights to optimize your applications, and ensure they are running smoothly. Another service essential monitoring system health is Sentry.io which provides client-side error notifications.