Testing & Debugging (Unit, Integration, Selenium)

Chapter 1
Foundations of Software Quality, Testing, and Debugging

Bachelors Program in Full Stack Development
Testing & Debugging (Unit, Integration, Selenium)   •   Bachelor

Foundations of Software Quality, Testing, and Debugging

Introduction

Software systems are judged not only by whether they execute, but by whether they satisfy stakeholder needs, protect information, remain maintainable, and behave reliably under expected and unexpected conditions. A banking application that calculates balances correctly but exposes customer data is not a quality product. Similarly, an online store that is secure and accurate but unusably slow may fail commercially.

Testing and debugging are therefore central software-engineering activities rather than final inspection tasks. Testing provides evidence about product quality and helps reveal defects. Debugging investigates the causes of observed problems and removes them. Neither activity can prove that a sufficiently complex system contains no defects; together with sound requirements, design, coding, review, deployment, and monitoring practices, they reduce risk.

This chapter establishes the conceptual foundation for unit, integration, and Selenium-based system or user-interface testing. It also explains how quality is managed throughout the software development lifecycle (SDLC).

Learning Objectives

After studying this chapter, you should be able to:

  • distinguish quality, verification, validation, testing, and debugging;
  • explain the relationships among errors, defects, failures, incidents, and risks;
  • classify testing by level, objective, technique, and execution method;
  • describe functional and non-functional quality attributes;
  • explain how testing is integrated into the SDLC;
  • select appropriate testing activities for a full-stack application;
  • analyse testing limitations, ethical responsibilities, and professional trade-offs.

1. Software Quality as a Multidimensional Concept

Quality is the degree to which software satisfies stated and implied requirements and provides value to its stakeholders. A requirement may be explicit, such as “the system shall allow a user to reset a password,” or implicit, such as reasonable accessibility, confidentiality, and responsiveness.

Quality is multidimensional. Common attributes include:

AttributeMeaningTypical evidence
Functional suitabilityCorrect and complete provision of required functionsAcceptance tests, requirements traceability
ReliabilityConsistent operation over time and under stated conditionsFailure history, recovery tests
Performance efficiencyAppropriate response time, throughput, and resource useLoad and stress tests
UsabilityEase with which intended users learn and operate the systemUsability evaluation, user testing
SecurityProtection of confidentiality, integrity, authenticity, and availabilitySecurity testing, audit findings
MaintainabilityEase of analysing, modifying, and testing the systemCode review, complexity and coverage evidence
CompatibilityAbility to coexist and interoperate with other systemsInterface and cross-browser tests
PortabilityEase of moving software between environmentsDeployment and configuration tests
AccessibilityUsability by people with diverse abilitiesKeyboard, screen-reader, and standards-based tests

Quality attributes can conflict. Strong encryption may increase processing cost; extensive logging may assist diagnosis but create privacy risk; a highly flexible architecture may be more difficult for beginners to maintain. Quality decisions should therefore be explicit, based on stakeholder priorities and risk.

Quality assurance (QA) is the planned, systematic set of activities used to provide confidence that processes and products meet requirements. Quality control focuses more directly on evaluating the product and identifying nonconformities. Testing is one quality-control activity, while reviews, process improvement, static analysis, configuration management, and operational monitoring also contribute to quality assurance.

2. Verification, Validation, Testing, and Debugging

These terms are related but not interchangeable.

Verification asks: “Are we building the product right?” It checks whether work products conform to specified requirements, designs, standards, and conventions. Examples include requirements reviews, design inspections, code review, static analysis, and checking database schemas against a design.

Validation asks: “Are we building the right product?” It evaluates whether the completed or partially completed system meets user needs in its intended context. Executing a realistic checkout scenario with representative users is validation-oriented.

A useful distinction is:

  • verification is primarily conformance to specified descriptions;
  • validation is primarily fitness for intended use.

Testing is the systematic examination of software, usually by evaluating behaviour through selected test conditions and comparing actual results with expected results. Testing includes planning, test design, environment preparation, execution, result evaluation, reporting, and closure. It may involve executing software or examining artefacts without execution.

Debugging is the process of locating, analysing, and correcting the cause of a failure or suspected defect. A typical debugging cycle is:

  1. reproduce or characterize the problem;
  2. collect evidence, such as logs, inputs, stack traces, and environment details;
  3. form and evaluate hypotheses;
  4. isolate the causal code, data, configuration, or interaction;
  5. apply a correction;
  6. perform targeted confirmation and regression testing.

Testing can reveal that a problem exists; debugging explains why it exists and changes the system. Testers and developers may collaborate, but the activities require different reasoning. Testing is investigative and evidence-oriented, whereas debugging is causal and corrective.

3. Errors, Defects, Failures, and Incidents

Precise terminology prevents confusion.

  • An error is a human action or decision that produces an incorrect result. A developer may misunderstand a tax rule or mistype a comparison operator.
  • A defect (also called a fault or bug) is an imperfection in a software work product resulting from an error. An incorrect operator in source code is a defect.
  • A failure is an observable deviation of the system from expected behaviour during execution. A customer being charged twice is a failure.
  • An incident is an event that requires investigation; it may be caused by a failure, an environmental condition, misleading test data, or an invalid expectation.

A defect does not always cause an immediate failure. It may lie in dormant code, require a rare input, or be masked by another condition. Conversely, an apparent failure may result from an incorrectly configured test environment rather than a product defect.

Defects are often classified by severity and priority. Severity describes technical or business impact: a security breach is normally more severe than a typographical error. Priority describes urgency of resolution. A low-severity defect on a highly visible marketing page may receive high priority, while a severe defect in an unused experimental feature may be scheduled differently. Severity and priority should not be treated as synonyms.

4. Fundamental Testing Principles

Several principles guide professional testing:

  1. Testing shows the presence, not the absence, of defects. Passing tests provide evidence for tested conditions; they do not prove universal correctness.
  2. Exhaustive testing is usually impossible. Input combinations, execution paths, environments, and user behaviours grow rapidly. Selection techniques are necessary.
  3. Early testing saves time and cost. Defects found in requirements or design are often cheaper to correct than defects found after release.
  4. Defects cluster. A small number of components frequently contain a large proportion of observed defects. Historical data and change patterns can guide risk-based focus.
  5. Pesticide paradox. Repeating an unchanged test set eventually finds fewer new defects. Tests need review, extension, and mutation of conditions.
  6. Testing is context-dependent. Safety-critical, medical, educational, and entertainment systems require different evidence and risk tolerances.
  7. Absence-of-errors fallacy. Software that conforms to its specification may still fail to meet real user needs if the specification is incomplete or wrong.

These principles reject two extremes: treating testing as a ceremonial final phase and expecting tests to guarantee perfection.

5. Test Levels

Test levels organize work according to the scope of the item being evaluated.

Unit or Component Testing

Unit testing examines a small, logically coherent part of a system, such as a function, class, module, or component. It is commonly performed by developers and should be fast, repeatable, isolated, and deterministic where possible. Dependencies such as databases or external payment services may be replaced by test doubles.

A unit test generally follows an Arrange–Act–Assert structure:

  • Arrange: establish inputs and conditions;
  • Act: invoke the unit under test;
  • Assert: compare actual and expected outcomes.

Unit tests are effective for boundary conditions, calculations, validation rules, error handling, and transformations. They do not by themselves demonstrate that modules communicate correctly or that the application meets user expectations.

Integration Testing

Integration testing examines interactions among modules, services, databases, APIs, queues, or external systems. For a full-stack application, examples include checking that a web API serializes data correctly, the service applies authorization, and the repository persists the resulting record.

Integration tests may use real dependencies, containers, controlled test databases, or carefully designed substitutes. The choice affects realism, speed, repeatability, and maintenance. A test that uses a real database may discover schema or transaction problems that a mock cannot reveal, but it requires environment control and data isolation.

System Testing

System testing evaluates the integrated application against system requirements. It may cover authentication, business workflows, error handling, performance, security, and compatibility. The test environment should resemble production sufficiently for the risks being evaluated.

Acceptance Testing

Acceptance testing determines whether the system is acceptable to customers, product owners, regulators, or operational stakeholders. User acceptance testing, contractual acceptance testing, and operational acceptance testing are examples. Acceptance criteria should be defined before testing where practicable, not invented to explain results afterward.

Regression Testing

Regression testing checks that changed code has not adversely affected existing behaviour. It may occur at every level. A focused regression suite is useful immediately after a change; a broader suite is valuable before release. Regression testing is not a separate scope level but a purpose that can apply to many tests.

6. Test Types and Techniques

Testing can be classified in several overlapping ways.

Functional and Non-Functional Testing

Functional testing examines what the system does: valid login, correct totals, authorization decisions, or API responses. Non-functional testing examines how well it does it: response time, accessibility, security, recoverability, and capacity.

Important non-functional tests include:

  • performance testing: response time, throughput, and resource behaviour;
  • load testing: behaviour under expected demand;
  • stress testing: behaviour beyond normal capacity;
  • security testing: resistance to unauthorized access and misuse;
  • usability and accessibility testing: effectiveness for intended users, including users with disabilities;
  • compatibility testing: browsers, devices, operating systems, and integrations;
  • recovery testing: restoration after faults or service interruption.

Black-Box, White-Box, and Gray-Box Testing

Black-box testing designs tests from externally visible behaviour without relying on internal implementation. White-box testing uses knowledge of code structure, paths, branches, or data flow. Gray-box testing combines external evaluation with partial internal knowledge. These are perspectives, not mutually exclusive careers or test levels.

Test Design Techniques

Equivalence partitioning divides inputs into classes expected to behave similarly. For an age field accepting 18–65, partitions might include below 18, 18–65, and above 65, with attention to boundary values.

Boundary-value analysis focuses on edges, such as 17, 18, 65, and 66. Defects frequently occur at transitions because of incorrect operators or assumptions.

Decision-table testing represents combinations of conditions and resulting actions. It is useful for pricing, authorization, and eligibility rules.

State-transition testing examines behaviour as an object moves among states. An account might move from Active to Locked after repeated failed logins and require a defined recovery path.

Use-case or scenario testing follows realistic user goals across system boundaries. It is especially valuable for system and acceptance testing.

Exploratory testing involves simultaneous learning, test design, and execution. It is structured by a mission or charter and benefits from skilled observation, note-taking, and risk awareness. It complements, rather than replaces, repeatable automated tests.

7. Test Automation and Selenium

Automation executes repeatable checks using software. It is particularly valuable for regression, data-driven checks, API contracts, cross-browser coverage, and frequent builds. Automation is not automatically superior: unstable tests, poor assertions, excessive coupling to implementation, and high maintenance can reduce its value.

Selenium is an open-source ecosystem commonly used to automate browser interaction. A Selenium-based test can locate elements, enter data, click controls, navigate pages, and verify visible outcomes across supported browsers. A robust browser test should:

  • select stable locators, preferably meaningful identifiers or accessible attributes;
  • wait for observable conditions rather than relying on arbitrary sleeps;
  • isolate test data and clean up after execution;
  • verify business outcomes, not merely that a click occurred;
  • capture screenshots, logs, and browser information when failures occur;
  • avoid excessive end-to-end tests when a unit or API test can provide faster feedback.

For example, a checkout test may navigate to a product page, add an item, authenticate a test user, submit payment using a sandbox, and verify the order confirmation. The same business rule—such as rejecting an expired card—may be tested more quickly at the service or unit level. A balanced test portfolio uses the browser for critical user journeys and lower-level tests for detailed rule coverage.

8. Testing Across the Software Development Lifecycle

Testing is most effective when integrated into the entire lifecycle.

SDLC activityQuality and testing contribution
RequirementsDefine acceptance criteria, ambiguity checks, risks, and testability
Architecture and designReview interfaces, failure modes, security, and observability
ImplementationUnit tests, static analysis, code review, and local checks
IntegrationAPI, contract, database, and component-interaction tests
System validationEnd-to-end, usability, compatibility, performance, and security tests
ReleaseRisk assessment, regression evidence, deployment verification, rollback readiness
OperationMonitoring, incident analysis, production checks, and feedback
MaintenanceChange-impact analysis, defect correction, and regression testing

In agile and continuous-delivery environments, tests are commonly incorporated into a continuous integration pipeline. A pipeline may run fast unit tests on every commit, integration tests on merged changes, and broader browser or performance suites at appropriate stages. The objective is not to maximize the number of tests but to obtain useful feedback at acceptable cost and risk.

Traceability links requirements, risks, test cases, defects, and results. It supports impact analysis and regulated evidence, but a traceability matrix is not proof of quality: a poorly designed test can be perfectly traceable and still ineffective.

9. Measuring and Interpreting Test Results

Metrics support decisions when interpreted in context. Useful measures include defect age, escaped defects, test execution status, failure trends, mean time to recovery, and coverage.

Code coverage reports which structural elements were executed by tests. Statement, branch, and condition coverage answer different questions. High coverage does not guarantee meaningful assertions, appropriate inputs, or correct expected results. Low coverage may identify risk, but a single universal coverage target is inappropriate for every system.

A simple test pass rate can be calculated as:

Pass rate = (number of passed tests ÷ number of executed tests) × 100%

The measure assumes that tests are classified consistently and that skipped, blocked, and inconclusive tests are not silently counted as passes. For example, if 92 of 100 executed tests pass, the pass rate is 92%. This does not mean that 92% of the software is correct; tests differ in scope and importance.

Risk-based testing prioritizes work according to likelihood and impact. A useful qualitative model is:

Risk priority = likelihood × impact

Here likelihood and impact are ordinal or numerical ratings defined by the organization; the product is a prioritization aid, not a natural law or precise probability. A high-impact payment failure may receive more attention than a low-impact formatting defect even if both are equally likely.

10. Illustrative Case: An Online Learning Platform

Background. A university launches a platform that allows students to enrol in courses, submit assignments, and view grades. The system includes a browser front end, REST API, relational database, and cloud file storage.

Problem. During a pilot, some students receive “submission successful” messages although their files are absent from the instructor view. A second issue allows a student to view another course’s draft feedback by changing an identifier in a URL.

Analysis. The first problem may involve an integration defect between the API and file-storage service, an asynchronous timing issue, or an incorrect transaction boundary. The second is an authorization failure: the system checks that a user is authenticated but does not adequately check ownership or course membership.

Approach. Developers first reproduce both failures using controlled accounts and test files. Unit tests are added for authorization decisions and submission-state transitions. Integration tests verify database records, file-storage responses, retries, and failure recovery. API tests confirm that unauthorized identifiers return an appropriate response without disclosing data. Selenium tests cover the critical student submission and instructor retrieval journeys. A security review and exploratory testing examine identifier manipulation, concurrent submissions, and interrupted uploads.

The pipeline runs unit tests on every change, integration tests before merging, and browser tests for release candidates. Test data is synthetic, and logs exclude student personal information.

Outcome. The authorization defect is corrected by enforcing server-side resource checks rather than relying on hidden interface controls. The submission workflow is changed so that success is reported only after the required persistence and storage confirmations occur. A compensating recovery process identifies incomplete submissions.

Learning points. End-to-end tests exposed the user-visible problems, but unit and integration tests made the underlying rules easier to isolate. Security cannot be inferred from a successful login test. A success message is itself a business claim and must be tested against durable evidence. Finally, privacy-preserving test data and operational recovery are part of quality, not optional extras.

11. Challenges, Ethics, and Professional Practice

Testing is affected by limited time, incomplete requirements, changing environments, flaky dependencies, nondeterministic behaviour, and pressure to declare readiness. Professionals should report evidence honestly, distinguish tested from untested areas, and communicate residual risk rather than hiding failures.

Security and privacy require special care. Test data should be minimized, anonymized, synthetic, or governed by explicit authorization. Tests must not attack production systems without permission. Defects involving personal data, safety, or security should follow responsible escalation and disclosure procedures.

Accessibility should be included from requirements onward. Automated accessibility tools are useful for detectable issues but cannot replace keyboard evaluation, screen-reader checks, and testing with representative users. Similarly, AI-assisted test generation can propose cases, locators, or code, but generated tests may encode incorrect assumptions, miss security risks, or reproduce biased data. Human review, controlled data, explainable decisions, and protection of confidential source code remain necessary.

Best practice is to build a layered, risk-based test strategy: prevent defects through clear requirements and reviews; detect them early with fast automated checks; validate critical journeys realistically; investigate failures systematically; and learn from production incidents. Quality is a shared responsibility among developers, testers, analysts, designers, operations personnel, managers, and users.

Chapter Summary

Software quality is multidimensional and includes functional suitability, reliability, performance, security, usability, maintainability, compatibility, portability, and accessibility. Verification checks whether work conforms to specified descriptions, while validation checks whether it meets intended user needs. Testing provides evidence by examining software behaviour and artefacts; debugging identifies and corrects causes of failures.

Errors are human actions, defects are resulting imperfections, and failures are observable deviations during execution. Unit, integration, system, and acceptance testing address different scopes. Functional, non-functional, black-box, white-box, exploratory, regression, and automated testing are complementary classifications or purposes. Selenium is valuable for critical browser journeys but should be balanced with faster unit and API tests.

Testing should be planned throughout the SDLC, supported by traceability, risk analysis, suitable metrics, ethical data handling, and honest reporting. No test suite proves the absence of defects. Effective quality engineering combines prevention, detection, diagnosis, correction, and continuous learning.

Key Terms

Quality: Degree to which software satisfies stated and implied needs.

Quality assurance: Planned activities that provide confidence in processes and products.

Verification: Checking conformance to specified requirements or descriptions.

Validation: Checking fitness for intended use and stakeholder needs.

Testing: Systematic evaluation of software or related work products.

Debugging: Locating and correcting the cause of a failure or defect.

Error: Human action or decision producing an incorrect result.

Defect: Imperfection in a software work product.

Failure: Observable deviation from expected behaviour during execution.

Incident: Event requiring investigation.

Unit testing: Testing an individual function, class, module, or component.

Integration testing: Testing interactions among components or systems.

System testing: Testing an integrated application against system requirements.

Acceptance testing: Testing used to determine stakeholder acceptability.

Regression testing: Testing to detect unintended effects of change.

Functional testing: Testing what the system does.

Non-functional testing: Testing quality characteristics of system behaviour.

Test automation: Use of software to execute and evaluate tests.

Selenium: Browser-automation ecosystem used for web application testing.

Risk-based testing: Prioritizing testing according to likelihood and impact.

Review Questions

Short Answer Questions

  1. Distinguish verification from validation.
  2. What is the difference between a defect and a failure?
  3. State two limitations of code coverage.
  4. Why are boundary values important in test design?
  5. Give one appropriate use of Selenium in a full-stack application.

Long Answer Questions

  1. Explain the relationship among errors, defects, failures, incidents, and debugging, using an example.
  2. Compare unit, integration, system, and acceptance testing in terms of scope and purpose.
  3. Discuss at least five software quality attributes and possible conflicts among them.
  4. Explain how testing can be integrated into each stage of the SDLC.
  5. Evaluate the benefits and limitations of test automation in a continuous-integration environment.

Analytical / Application Questions

  1. Design a layered test strategy for an online payment feature. Justify which checks belong at unit, integration, API, and browser levels.
  2. A test suite reports a 98% pass rate, but users report frequent failures. Analyse at least four possible explanations and propose evidence to collect.
  3. An application displays a successful file-upload message before the file is durably stored. Analyse the likely quality risks and design tests and corrective actions.

Multiple Choice Questions with Answers

Question 1

Which statement best distinguishes validation from verification?

A. Validation checks whether the product meets intended user needs; verification checks conformance to specified descriptions.

B. Validation is performed only by developers; verification is performed only by users.

C. Validation executes code; verification never examines software artefacts.

D. Validation measures performance; verification measures security.

Correct Answer: A. Validation checks whether the product meets intended user needs; verification checks conformance to specified descriptions.

Question 2

A developer misunderstands a tax rule and implements the wrong calculation. The misunderstanding is primarily a:

A. Failure

B. Human error

C. Regression test

D. Quality attribute

Correct Answer: B. Human error

Question 3

Which test level focuses most directly on interactions between an API, database, and file-storage service?

A. Unit testing

B. Integration testing

C. Acceptance testing only

D. Exploratory testing only

Correct Answer: B. Integration testing

Question 4

Which technique is most appropriate for testing inputs at the edges of an accepted range?

A. Boundary-value analysis

B. Random code formatting

C. Code deployment

D. Static linking

Correct Answer: A. Boundary-value analysis

Question 5

Why should browser automation avoid arbitrary fixed sleeps where possible?

A. They make source code impossible to compile.

B. They can make tests unnecessarily slow and unreliable when timing varies.

C. They prevent all security testing.

D. They eliminate the need for assertions.

Correct Answer: B. They can make tests unnecessarily slow and unreliable when timing varies.

Question 6

If 92 of 100 executed tests pass, what is the pass rate?

A. 8%

B. 90%

C. 92%

D. 108%

Correct Answer: C. 92%

Question 7

Which statement about testing is correct?

A. A passing test suite proves that no defects exist.

B. Exhaustive testing is normally easy for complex systems.

C. Testing provides evidence about quality but cannot generally prove defect absence.

D. Testing and debugging are identical activities.

Correct Answer: C. Testing provides evidence about quality but cannot generally prove defect absence.

Question 8

Which quality attribute concerns protection of confidentiality, integrity, authenticity, and availability?

A. Security

B. Portability

C. Usability

D. Maintainability

Correct Answer: A. Security

Question 9

A test that checks whether a user can complete a realistic checkout journey is primarily a:

A. System or end-to-end test

B. Syntax test

C. Unit-only test

D. Compiler test

Correct Answer: A. System or end-to-end test

Question 10

What is the main purpose of regression testing?

A. To replace requirements analysis

B. To detect unintended effects of changes

C. To guarantee zero production incidents

D. To measure employee productivity

Correct Answer: B. To detect unintended effects of changes

Testing & Debugging (Unit, Integration, Selenium)
Chapter 1 of 14