STUDY GUIDE · CLO 11 · CODE COVERAGE · WEEKS 14–15

Test cases and code coverage

How to write a test case as evidence for a decision, where it sits among the testing strategies, and what code coverage does and does not tell you. You practise this in the tests and the coverage step of every Python build (Assignments 3–9), and it is part of the final examination.

باختصار

هذا الدليل يغطي موضوع «تغطية الشيفرة» في توصيف المقرر، ومخرج التعلم 11: تصميم حالات الاختبار وتنفيذها في استراتيجيات الاختبار المختلفة. تتدرّب عليه في خطوة التغطية في كل بناء برمجي (الواجبات 3–9)، وهو ضمن الاختبار النهائي. اقرأ الأقسام الأربعة، ثم جرّب المثال المحلول، ثم أجب عن أسئلة المراجعة.

Reading: I. Sommerville, Software Engineering, 10th edition, Chapter 8 (Software testing): 8.1 development testing, 8.2 test-driven development, 8.3 release testing, 8.4 user testing.

1 · Testing strategies and levels استراتيجيات الاختبار ومستوياته

LevelWhat it checksWhere you meet it in this course
Development testing · unitOne function, method or class on its own.Every build: your test_ functions call one function.
Development testing · componentSeveral units through their interface; interface misuse and timing.Chapter 16: the interface contract.
Development testing · systemThe integrated system, including the interactions between components.Chapter 20: cross-owner interaction testing.
Release testingA separate team checks the system against its requirements before release; requirements-based, scenario and performance testing.Chapter 11: statistical testing with an operational profile.
User testingAlpha, beta and acceptance testing by users or the customer.Chapter 20: staged acceptance.

2 · Writing a test case as evidence حالة الاختبار دليلاً

In this course a test is evidence for a dependability decision: it shows that a requirement holds, that a misuse is refused, or that a changed condition is handled.

Source of the testWhat you writeExample from the builds
From the requirementTurn each requirement or course check into at least one test that asserts the expected result.Each course check in a build is a requirement test.
What is allowed and what is refusedTest the normal case and the case that must be refused, including missing or invalid data; check that the refusal fails safely.A record without "loans"; loans given as text.
Misuse casesTurn a misuse case into a test that the attack or misuse is refused.Chapter 13: misuse cases become tests.
The changed conditionWhen new evidence changes a condition (STRESS), add a test for the new condition before you change the code (REFIT).The REFIT step in Assignments 3–9.
Test-driven developmentWrite a failing test, write the code that passes it, then refactor.Run your tests after each change in a build.

Scope. Systematic test-design techniques, such as equivalence partitioning, boundary-value analysis, decision tables, path coverage and random or automated test generation, are the subject of a dedicated software-testing course. They are not taught or assessed in CPIT-455.

حدود الموضوع: تقنيات تصميم الاختبار المنهجية، مثل تقسيم التكافؤ وتحليل القيم الحدّية وجداول القرار وتغطية المسارات والتوليد العشوائي أو الآلي للاختبارات، موضوع مقرر مستقل في اختبار البرمجيات، ولا تُدرَّس ولا تُقيَّم في هذا المقرر.

3 · Coverage measures مقاييس التغطية

CriterionDefinitionIn this course
Statement (line) coverageShare of executable statements run at least once by the tests.The build record reports it for your own code.
Branch (decision) coverageShare of decision outcomes (each if true and false; each loop entered and skipped) taken by the tests.The build record lists every branch your tests did not take.

What coverage does not show. Coverage tells you which code your tests ran, not whether they checked the result. Code that was never written, such as a missing check, cannot be uncovered. Treat coverage as a map of what is still untested, not as a score. Mutation testing, used in every build, asks the stronger question: would a test fail if the code were wrong?

ما لا تُظهره التغطية: التغطية تبيّن أي جزء من الشيفرة نفّذته اختباراتك، ولا تبيّن هل تحققت الاختبارات من النتيجة. والفحص الناقص الذي لم يُكتب أصلاً لا يظهر في التغطية. لذلك تستخدم البناءات اختبار الطفرات أيضاً.

4 · Coverage tools أدوات التغطية

LanguageToolTypical use
Pythoncoverage.pycoverage run --branch -m pytest, then coverage report -m (lists the lines not run)
JavaJaCoCoMaven or Gradle plugin; HTML report of line and branch coverage
JavaScriptIstanbul (nyc) or c8nyc npm test, or c8 node --test
C and C++gcov / lcovcompile with --coverage, run the tests, then gcov or lcov

The build in your assignment measures line and branch coverage of your own functions (not of the test_ functions) in the browser, so you do not need to install a tool.

5 · Worked example مثال محلول

The complete solution of the practice build has four tests: a normal loan, a third item, an overdue student and a broken record.

def can_borrow(student, item):
    try:                                                        # line 2
        loans = student["loans"]                                # line 3
        if type(loans) is not int or loans < 0:                 # line 4
            return False                                        # line 5
        return item["available"] is True and loans < LIMIT and student["overdue"] is False   # line 6
    except (KeyError, TypeError):                               # line 7
        return False                                            # line 8

6 · Check yourself راجع نفسك

Answer first, then open each question.

1. Does 100% statement coverage guarantee 100% branch coverage?

No. An if without an else can have every statement run by a test where the condition is true, while the false outcome is never taken. Branch coverage includes statement coverage, not the other way round.

2. Your tests reach 100% line coverage and all pass. Is the code correct?

Not necessarily. Coverage shows that code ran, not that a test checked its result. A test without an assert can run every line. That is why the builds also use mutation testing: each known faulty version must make at least one of your tests fail.

3. A requirement says: "a student with an overdue item cannot borrow." Write one test for it.

Build a student record with overdue set to True and an available item, call can_borrow, and assert that the result is False. Name the test after the requirement, for example test_overdue_student_is_refused.

4. At which testing level do you check that two components owned by different teams work together?

Component or system testing (integration). In a system of systems (Chapter 20) this is cross-owner interaction testing.

5. The coverage report lists the branch "if type(loans) is not int or loans < 0 → true" as not taken. What do you do?

Add a test whose input makes the condition true, for example loans = −1 or loans = "2", and assert that the result is False. Then run the build again and confirm the branch is now taken.

7 · For the final examination للاختبار النهائي

Back to the learning path · CLO 11 in the course specification