π§ͺ Testing π
A complete guide to software testing: unit tests, integration tests, end-to-end testing, and best practices for maintaining code quality.
Testing
- Business -Business user define the problem only (& not venture into suggesting any solution)
- Development - Developers suggest ways to fix the problem
- Testing - Tester question the solution by bring up as many as many What-If
Keep Unit smaller
- Reduced debugging effort, smaller units aids in tracking down errors.
- Small test cases are easier to read and to understand.
- Developer writing tests may share blind spots with the code
- High number of passing unit tests may bring a false sense of security.
- Tests become part of the maintenance overhead of a project.
- Fragile test cases block the release.
- Generated code may give wront coverage report.
- Change in design break test case.
- Must add estimation of test case when estimating story
Limitation
- Test only small unit not the BDD
- DB & N/W Simulation
- Management may feel that time spent writing tests is wasted
Test-driven development TDD
Software-development methodology which essentially states that for each unit of software, a software developer must:
- define a test set for the unit first;
- make the tests fail;
- then implement the unit;
- finally verify that the implementation of the unit makes the tests succeed.
Advantage
- encourages simple designs and inspires confidence
Acceptance testβdriven development(ATDD)
-
Acceptance Test created when the requirements are analyzed and prior to coding usually in Xray
-
Test defined in plain language with steps for Developer, QA & business
Given Book that has not been checked out And User who is registered on the system When User checks out a book Then Book is marked as checked out -
Developer-tester-business customer collaboration while TDD is only for devs
-
Written even before coding so that Dev can check if all requirement are fullfilled
Behavior-driven development BDD
Specifies that tests of any unit of software should be specified in terms of the desired behavior of the unit
-
focuses on tests which describe behavior, rather than tests which test a unit of implementation in TDD
private Game game; private StringRenderer renderer; @Given("a $width by $height game") public void theGameIsRunning(int width, int height) { game = new Game(width, height); renderer = new StringRenderer(); game.setObserver(renderer); } @When("I toggle the cell at ($column, $row)") public void iToggleTheCellAt(int column, int row) { game.toggleCellAt(column, row); } @Then("the grid should look like $grid") public void theGridShouldLookLike(String grid) { assertThat(renderer.asString(), equalTo(grid)); }
BDD Test case
Given a 5 by 5 game
When I toggle the cell at (3, 2)
Then the grid should look like
Continuous test-driven development(CTDD)
- Extends test-driven development (TDD) by automatic test execution in the background.
- With each push of code CI/CD run tests
Code Refactor
Process of restructuring existing computer code without changing/breaking its external behavior.
Advantages
- Important step of TDD. Give confidence that code is not broken.
- improved code readability and reduced complexity
- improve the maintainability by making easier to fix bugs
- create a simpler, cleaner, or more expressive internal architecture or object model to improve extensibility.
- improved performance
Steps to Refactor Project
Get Understanding of Code
- Program Dependence Graph - explicit representation of data and control dependencies
- System Dependence Graph - representation of procedure calls between PDG
- Software intelligence - reverse engineers the initial state to understand existing intra-application dependencies
Add Abstraction
- Encapsulate field β force code to access the field with getter and setter methods
- Generalize type β create more general types to allow for more code sharing
- Replace type-checking code in switch with state/strategy of subclass
- Replace conditional with polymorphism of sub class
Break down Code
- Componentization: breaks code down into reusable semantic units that present clear, well-defined, simple-to-use interfaces.
- Extract class: moves part of the code from an existing class into a new class.
- Extract method: to turn part of a larger method into a new method. By breaking down code in smaller pieces, it is more easily understandable. This is also applicable to functions.
Improve name & location
- Move method or move field β move to a more appropriate class or source file
- Rename method or rename field β changing the name into a new one that better reveals its purpose
- Pull up β in object-oriented programming (OOP), move to a superclass
- Push down β in OOP, move to a subclass
- Automatic duplicate code detection
