Skip to main content
Introduction to Devops

Testing, Code Inspection, and Continuous Integration

Published: 2026-08-14
Level: postgraduate
Audience: Postgraduate students of software engineering and delivery

Testing, Code Inspection, and Continuous Integration

This session completes the build process picture. We first cover unit testing — what changes when we test small pieces of code instead of the whole system — then functional test automation with Selenium, then continuous code inspection with SonarQube, and finally continuous integration: the practice that ties version control, build, testing, and inspection together. A long exam-orientation discussion for the mid-semester examination opens the session, and the last topic, continuous integration, is the final syllabus point before that exam.

10.1 Mid-Semester Exam: Format, Logistics, and Preparation

The session opens with a long question-and-answer round about the mid-semester examination. This section collects every piece of exam intel given during that discussion: the question style, the answering strategy, the syllabus coverage, the logistics of the online open-book format, and a practical study plan.

10.1.1 Question Patterns: Scenarios, Not Commands

The first and most repeated answer concerns question style — will the exam ask about tools directly?

Q: Will there be any particular questions on Jenkins or AWS? Should we expect direct questions on tools? A: No. There will be no direct questions that ask you to write a script, write a command, write some code, or write a pipeline. The questions will be scenario based: "This is the problem — which tool chain probably helped to get out of this particular problem?" You answer by recommending a tool chain. If the scenario is a continuous integration problem, you can suggest any continuous integration system like Jenkins or CircleCI — that is absolutely fine.

There will be no direct questions about tool features either. Jenkins is not part of the syllabus for the mid-semester examination. For the comprehensive examination you might still expect a conceptual question — something like whether Jenkins is distributed or centralized, or whether it supports both — that kind of conceptual question is possible. But nothing that asks you to write a script or write commands.

Git gets the same treatment. There will be no questions that say "write a Git command with this specification" — no scenario like "team members want to push code, this is the repository, write the command to push it upstream." Instead you can expect conceptual questions such as the difference between merge and pull, or between revert and reset.

Exam note: The whole exam is scenario based, not command based. What is being tested is your ability to look at a problem and name the tool chain that solves it — so study what each tool does and where it fits, not the exact syntax of its commands.

10.1.2 How to Answer by Marks

The length of your answer should follow the marks of the question. If it is a five-mark question, there should be five different points covering the scenario, and doing that is what earns the marks. If you just write two or three pages of theory where nothing is in line with the scenario that is expected, you will score zero. For a one- or two-mark question, two or three lines with the point stated is good enough. Match the number of points to the marks.

Exam note: Treat the marks as a budget. Five marks means five distinct scenario-relevant points; one or two marks means two or three lines with the point stated. Unrelated theory, however long, is worth zero.

10.1.3 Syllabus Coverage

The course handout contains nine modules in total. The mid-semester examination covers five and a half modules — it does not run through contact session nine or modules one to eight in full. A note on the exact mid-semester syllabus will be published on the course channel, so keep an eye on it.

Exam note: The mid-semester examination covers five and a half of the nine modules in the course handout. Watch the course channel for the exact syllabus note, and expect a scenario-based question from the automation part of this module (Selenium and SonarQube territory). There will definitely be questions on code inspection and on testing. The next session will go through last year's question paper, which is available on the course portal — that paper is the best preview of what the exam looks like.

10.1.4 Open-Book Online Exam Logistics

Confirmation was sought on whether the examination is open book. The course handout says closed book — that is the standard that is normally followed. But because of the pandemic, the examination will again be online this semester rather than offline, and an online exam means an open-book examination, conducted through the online exam platform. Expect scenario-based questions in that setting.

On materials: you are not sure whether toggling between tabs will be allowed, so stay on the safe side. Take printouts of the presentation PDFs and keep your own notebooks — the notes you made during classes — with you. If you are carrying them and the instructions say soft copies are allowed, that is fine too; an open-book online exam definitely means you can use soft copies from your laptop.

Diagrammatic questions work differently. When a question asks you to draw — draw an architecture, draw a component design — the answer will be handwritten. You draw it, take a snapshot, and upload it. If you are not comfortable writing by hand, a text option is also there: you get a text box where you can type in, and that is completely fine. Mixing is allowed — some answers typed online and others handwritten — so one question can be answered in the text box and another can be a drawing.

Exam note: The exam is open book only because it is online. Carry printouts of the deck PDFs and your class notebooks so you are safe whether or not tab-switching is allowed; soft copies on your laptop are permitted. For draw-a-diagram questions you can upload a photo of your handwritten answer or type in the text box — either mode is accepted, and you can mix them question by question.

10.1.5 Study Plan, Reference Books, and Quizzes

On reference books: you will not be spoon-fed a single textbook. Instead, for each contact session you are told which chapter of which textbook was found useful. Compile those references, then take your own call — buy one book and keep the others as PDF copies. Take printouts of the PDF chapters of the particular chapters and keep them handy for the examination.

A practical study order was given to students short on time:

Q: If I do not have time, what should I prepare first for the examination? A: First, give focus to the presentation deck. Second, go through the recorded sessions which we covered in the contact sessions. Third, if you get more time, refer to the content from the textbook to understand it thoroughly. Frankly, if you go through the deck and the recorded sessions, that will be enough for you to clear the examination.

Exam note: Do not copy-paste — not from some web portal and not from the presentation deck as it is. That is not expected in the exam. The examination is for you: the concepts have been covered in class, and how you understood them and the way you write them must come in your own language.

On the tutorial sessions: there are four tutorial sessions, two already completed, and a quiz is uploaded after each. Quiz one and quiz two are done; if you missed them, it is now mandatory to attend quiz three and quiz four, because out of the four quizzes the best two will be considered. Tutorial session recordings are available, so you can go through them. The tutorial roadmap: one session was purely on Git; the upcoming sessions cover Maven, then Selenium and SonarQube, and the last one is purely on Jenkins — implementing a CI/CD pipeline.

10.2 Unit Testing: Testing Pieces Instead of the Whole

10.2.1 The Agenda for the Build Process

The syllabus agenda for this stretch of the course is the further components of the build process and how to automate them: unit testing, other subsequent testing types, automating the test suite with Selenium (that is the functional test), and then continuous code inspection — what the practices are, what continuous code inspection means as a process, and automating it with SonarQube. That is roughly a two-session agenda; today covers unit testing, Selenium, and code inspection, and continuous integration starts at the end.

Think of the build process as an assembly line. Earlier sessions covered version control (where the code lives) and the build itself (how source becomes a runnable artifact). This session adds the quality checks that run on that line: unit tests catch broken parts at the start, Selenium checks the finished behavior through the browser, SonarQube scans the code for hidden defects, and continuous integration — the final topic — wires the whole line together so it runs on every commit.

10.2.2 Traditional Testing and Its Problems

Before defining unit testing, contrast it with the traditional way of working. In the traditional approach we tested the system as a whole — we never tested small components of the code. Only once the complete code base and complete functionality were ready did we test the entire system.

Because testing happened at the end, there were a lot of chances that errors went undetected while coding. Most of the time those errors used to go undetected, and we used to get them in the production environment — reported by your end customer. Isolating errors was also difficult: the code base is huge, and figuring out from which source code a particular bug was triggered used to be difficult.

The traditional approaches used to follow for testing were print statements, use of debuggers, debugger expressions, and test scripts — those were the basic approaches. Each of these is manual: a human reads output, a human steps through a debugger, a human interprets a script's result. None of them ran automatically when the code changed, and none of them told you which line of a large code base caused the failure.

10.2.3 What Unit Testing Is

Unit testing is a level of the software testing process where individual units — individual components of your software, your project, or your system — are tested. Instead of testing the entire system, we test a small piece of code, one unit of code, individually.

Think of a software system made of components: the login page component, the payment gateway component, the search engine component, the e-card component of the application. With unit testing, every component is tested individually, at least once, to find any bugs or defects.

A unit is the smallest testable piece of your code — typically one function, one method, or one class. The textbooks phrase it exactly this way: a unit test is a code-level test of an individual class or method, checking functionality that relies only on that piece of code. Because the unit is small, it runs in milliseconds, and it does not need the database, the file system, or the network to be available.

This changes the timing of error discovery. Errors get picked up early because you do not have to wait until all functionality is ready: if the login page is ready, you immediately apply unit testing to find errors in that particular part of the code. The scope is smaller, so it becomes easy to find where a particular error was triggered, and it is easy to fix the same. Typically unit test scripts are written and run by the software developers themselves, because those are the people really closest to the code — they can write the unit tests and run them to understand if there are any issues.

10.2.4 Worked Example: Unit-Testing a Login Page

The clearest example is a code base for a login page, with a login ID field, a password field, and a login button to click and get logged in.

Setting: sign-up logic for a web application. The production code enforces a password rule: a password shorter than 8 characters must be rejected with a "password not accepted" message.

Unit test 1 — the password rule:

  • Input: a password of four characters, and that too all numerical characters, say 1234.
  • Expected behavior: the sign-up code rejects it and raises the error that tells the user this password will not be accepted.
  • The test feeds 1234 in and checks: does the error trigger? If it does not trigger the error that notifies the user, then there is a problem in your code base — you have to refactor it to make it much stronger in letting your customer know.

Unit test 2 — the login button:

  • Action: click the login button.
  • Expected behavior: the code shifts the window to the other panel of the software.
  • The test performs the click and checks whether the navigation happened. If it does not, you write a test for that too.

The point: instead of doing these checks manually — typing a weak password yourself, watching whether the error appears, clicking the button and looking at the screen — you do them at code level. The test runs the same check automatically, every time, with the same inputs, and reports pass or fail in a fraction of a second.

Unit testing also helps us calculate code coverage. When you run the unit tests, how many lines of the production code that has been written actually got executed — those lines are nothing but your code coverage. In other words, code coverage is the share of the production code that the unit tests exercise, expressed as a percentage:

To read the formula: the numerator counts every line the tests actually ran through; the denominator is every line of production code that was written. The ratio tells you how much of the code the test suite touched. If a line of production code is never executed by any unit test, that line's behavior is simply untested — and a bug sitting there can pass the whole suite unnoticed.

A coverage calculation with real numbers. Suppose the login and sign-up module contains 500 lines of production code. The unit tests for the module execute 385 of those lines:

Step by step: 385 ÷ 500 = 0.77, and 0.77 × 100 = 77. So the tests cover 77 percent of the module. The remaining 115 lines — for example the "password rejected" error branch, if the test never feeds a weak password — were never executed, so nothing proves they work. A sense-check: the answer 77 percent is less than 100 percent, which matches the fact that some lines were not exercised.

10.2.5 Goals and Benefits

The goal of unit testing is to isolate each part of the program and show that the individual parts are correct. That is what we want to achieve. Why unit testing? It is concerned with the functional correctness and completeness of your unit or component. It helps you effectively handle errors. It helps you check the input value parameters — whether the input values you pass are in line with what has been written in the production code. It helps confirm the correctness of output — whether the returned value is correct or not. And it helps to optimize the algorithm and the performance of your component.

Put all of these factors together and you achieve: faster debugging, faster development, a better design, an excellent regression tool, and reduced future cost — because you are getting errors early, and the errors are isolated, so fixing them is easier and costs much less.

Why the order matters: the entire automated test suite doubles as a regression suite — a net that catches any change that breaks existing functionality. Whenever a developer changes the login code, running the login unit tests plus every other unit test shows within seconds whether the change broke something that used to work. That is why the textbooks call the test suite the living documentation of the production system: the tests are an executable description of what the code actually does, and they are never out of date.

There are further benefits worth keeping. Unit testing allows a programmer to refactor the code earlier and make sure the individual modules of the project work correctly. By testing the parts of the program first and then testing the sum of its parts, integration testing becomes easier: every individual part is already tested, so combining components into the whole system produces fewer defects found in integration testing, because the errors have already been covered at the individual level. Unit testing also provides a sort of living documentation of the production code — the unit tests themselves are the living document of the production system.

10.2.6 Guidelines for Unit Tests

A reassurance first: automating anything is not rocket science. Automation here just means you write a script that gets run and that script automates the particular job.

Unit tests are code, so the guidelines for unit testing mirror the guidelines we follow for source code. A unit test suite that is small, fast, and independent is a tool the whole team can trust; a suite that is slow and fragile quietly stops being run, and then it stops protecting anything.

  • Keep unit tests small and fast.
  • Unit tests should be fully automated and non-interactive.
  • Make unit tests simple to run.
  • Measure the tests — ways of measuring exist, code coverage being one; you get your percentage, and percentages of tests passed like 80 percent, 70 percent are your measures.
  • Fix failing tests immediately — if there is any failure in the unit test, the first thing you do is fix that failure.
  • Keep testing at the unit level.
  • Keep tests independent.
  • Name tests properly — if the test script is written for login and sign-up and that too for the password, and it is written modularly, the name should be proper, like "test report login sign-up password", so that other team members can understand the purpose of writing this particular test.
  • Prioritize your testing as well.

Scope — where the formula and the approach apply, and where they break.

  • Coverage measures quantity, not quality. The professor's formula counts executed lines; it says nothing about whether the test asserted the right thing. A test can run through a line and check nothing — the line counts as "covered" while its behavior stays unverified.
  • The textbooks set the practical floor at about 80 percent coverage for unit tests, and industry gates often do the same. But the books also warn that coverage alone is a poor metric: the quality of the tests matters far more than the raw percentage.
  • Unit tests deliberately avoid the database, the file system, and the network so they stay fast. That speed has a price: bugs that only appear when components talk to each other will escape unit testing and have to be caught by the integration and functional tests covered later in this session.
  • A unit test that depends on another test's result, or on a shared external resource, is not independent — run in a different order it can fail for the wrong reason.

10.3 Automating Functional Testing with Selenium

10.3.1 Scope of Test Automation in This Course

Testing covers a huge scope, so as part of an introduction to DevOps we touch only one type: functional testing, and how to automate it with Selenium. Other types exist — for acceptance testing you have Cucumber, for performance testing there are other tools and technologies in the market — but due to scope constraints they are not covered in the syllabus. When it comes to functional or system tests involving web browser interaction, Selenium is the tool widely accepted by most organizations. That does not mean Selenium only supports web browser interaction — some organizations use Selenium for their mobile applications as well — but Selenium got famous for automating web browser interaction, and to date, for functional testing of web-based applications, most organizations opt for Selenium.

10.3.2 What Selenium Is and Its Benefits

Selenium performs a sort of interaction: it automates web browser interaction. Since it is automation, you write a script that performs the interactions. The benefits of Selenium:

  • Frequent regression and integration testing. The same browser test script can be rerun again and again, so checking that old functionality still works becomes a routine event instead of a project.
  • Rapid feedback to the developers. Once you commit code, the integration server build process gets triggered; the build process runs the unit tests, the Selenium tests automatically follow afterwards, and if there are any failures or errors, the feedback rapidly reaches the developer — it is a fast feedback loop.
  • Virtually unlimited execution of test cases. A script does not get tired; the same suite can run hundreds of times a day.
  • Support for agile and extreme development methodologies.
  • Disciplined documentation of test cases. The scripts themselves record exactly what was tested and how.
  • Customized defect reporting.
  • Finding defects missed by manual testing. Because the process is automated, there are no manual errors and no missed use cases, so it definitely helps find defects that manual testing would miss.
  • Reduced business expenses. There is an upfront cost: you need to train people to use Selenium, and training costs. But once the setup is ready, expenses drop — you do not need two or three testers doing manual tests; two testers write scripts and the other two upskill by learning new automation tools and automating other types of testing. Time is reduced and time to market is increased.
  • Reusability. The test script you write can be reused in another similar web development project, in any other domain with the same characteristics, with a little customization.
  • Faster time to market, achieved by reusability and by reducing manual testing time.

10.3.3 How Selenium Works: The Login-Page Walkthrough

The core logic of how Selenium works comes through best with the login page scenario. Manually, you would enter a username, enter a password, and click on login. Then you check: with a correct username and correct password, am I getting logged in and pushed to the other page of my software? If I keep the password blank, does the system throw an error that the password is incorrect? If I give any one input incorrectly, does the system give me an error that the inputs are incorrect? That is the manual way of testing.

The same walkthrough, automated with Selenium. With Selenium you use the Selenium libraries. Those libraries help you identify the web page elements. Based on those elements you write the test script. What will be the content of the test script? The input is the web element: you provide some values to those web elements, and you do the actions. At a high level, you do three things:

  1. Identify the web elements on that particular page — say name, email, investment, date, joint, active; you extract those web elements and learn the names of those web elements.
  2. Write the test script with the ID or XPath of those elements, preferably in your own preferred programming language — the reference script shared in this course was written in Python.
  3. Pass values to the web elements and run those test cases. For example: identify the name element, give a value to the name; identify the email element, give certain values to the email; if name and email are incorrect while I click on the OK button, check whether the system gives me an error.

That is how automation replaces the manual walkthrough: the three manual steps — type, click, observe — become a script that performs the same actions and checks the same reactions, automatically and repeatedly.

10.3.4 Finding Web Elements with Browser Developer Tools

A tester is often not the developer. Say the system was developed by someone else and you are just accessing it randomly — you still need the element names so you can write your automated script. The way to find them: the browser development tools, which most people already know. Navigate to the page, click, and inspect; the tool shows the name of each component.

Reading element names from an internal site. The username field's name is "text email" (txtemail); the password box's name is txtpass; the login button's name is button1. What could be the action? Click — click is the action.

So in the Selenium script you write the element's ID or XPath — something like ID or XPath equals txtemail — give that element a name, like username, and then pass the value to it. Then do the same for txtpass, and for button1 the action is click. This is how you write your test script on web-based elements. The same script will be shared after the tutorial session so you get a clear idea.

10.3.5 The Four Components of Selenium

Selenium has four components, out of which one is already deprecated.

Selenium IDE is the component with which Selenium was introduced and with which it gained attraction in organizations for automating functional testing. IDE is a record-and-playback plugin for the Firefox browser. How it worked: first phase — run it manually. You click on the IDE plugin and click on record. Once you click record, you are supposed to do some manual actions: sticking to the login page example, you type in a login ID and password and click the login button. That set of actions gets recorded — whatever manual testing you did the first time is recorded. Next time, if any code change happens, you do not have to do it manually; you just click play and automatically every step you recorded executes with automation. Selenium IDE helps in achieving prototyping testing.

Selenium RC (remote control), also known as Selenium 1, used to execute scripts written in any language — C++, C, any language you are comfortable with. However, the script used to execute using JavaScript. Selenium 1 is deprecated; nobody uses it because it is not actively supported even by Selenium.

WebDriver is the most actively used component today. It is an API used to interact directly with the web browser. It is the successor of Selenium 1 and Selenium RC — Selenium RC and WebDriver were merged to form Selenium WebDriver, also known as Selenium 2. WebDriver exists per platform: whatever browser or platform you work on — Google Chrome, Firefox, IE — you download the Selenium WebDriver for that particular platform. The automation demo in the tutorial session will use the WebDriver component, and the shared script runs on WebDriver.

Selenium Grid is the fourth component. It is a tool to run tests in parallel across different machines and different browsers simultaneously, to parallelize your test execution phase on different machines and different browsers. Selenium Grid is what organizations generally use to parallelize their test cases; it is used to minimize execution time.

Component What it does Status today
Selenium IDE Record-and-playback plugin for Firefox; you record manual actions once, then replay them on every code change The original, used for prototyping testing
Selenium RC (Selenium 1) Executed scripts of any language via JavaScript Deprecated — no longer actively supported
WebDriver (Selenium 2) API that talks directly to the browser; one WebDriver per browser/platform The actively used component
Selenium Grid Runs the same tests in parallel across machines, browsers, and devices to cut execution time Used by organizations to parallelize test cases

10.3.6 Platforms Selenium Supports

Selenium supports all browsers — Firefox, Chrome, IE, Safari, Opera — all are supported. If you work with Selenium WebDriver you just need to download the particular WebDriver for the particular browser: if you are working on IE, search for the IE WebDriver and download it, and then you can integrate Selenium libraries and automate the testing that is to run on Internet Explorer.

For operating systems, Selenium supports all platforms: Windows, Mac OS, Linux, Solaris. For languages, it supports all languages — there is no language barrier. If you are comfortable with Python you can write scripts in Python; if you are comfortable with C Sharp, Java, or Perl, use those. The only constraint is that you need the particular Selenium libraries for your language.

10.3.7 Architecture: Client–Server and the Grid

Selenium works on a client–server architecture. On the client side there are two components: the WebDriver API and the remote WebDriver. The WebDriver API helps you write the automated scripts; the remote WebDriver API connects to your remote server. On the server side you have the server component, the WebDriver API, and Selenium Grid. The server component receives the interactions from your client; the WebDriver API runs those test scripts and brings in the automation; Selenium Grid allows your team to start using the grid feature to parallelize the test scripts.

How does Selenium Grid work? With Selenium Grid you have a Selenium hub. The hub lets you write the script once, and that script can be executed in parallel across all different platforms and all different browsers simultaneously. Looking at the diagram: one test script runs across Mac, Windows, and Linux; within Windows you can run simultaneously on Firefox, Google Chrome, IE, and Opera; for devices, you can simultaneously run those test scripts on tablets, mobiles, computers, and laptops. That is the grid feature.

A caution: the grid is a bit complex, and it is not easy to get started with it right away. First understand Selenium — start writing a small script. As shown, find an element on any public website with the development tools, get the component names, and start writing scripts in your preferred language until you are used to Selenium. Then you can jump to the Selenium official documents, which are really strong documents — all the cases are written and very well organized — and you will be able to start using the grid after you get a little bit handier with Selenium.

10.3.8 Student Questions: Grid Logic, Test Ownership, Time, and TDD

A set of questions about how the grid works, who owns which tests, and how TDD relates to unit testing closed this topic.

Q: Can we use the same test script and test cases across all the nodes in the grid? A: Yes, you can use the same test cases across all the nodes. You just need to write the logic behind it. Say it is getting executed on Chrome — inside there is logic written for Chrome to execute that test script; if it is on a different device, the logic for that device is inside it. You can create a modular way of working with the grid feature of your Selenium.

A second question turned to who should carry out unit testing.

Q: Should unit testing be done by the testing team or the development team? A: Unit testing should be done by the development team, not by the testers. And do not keep it as "developer or tester" — we are talking about DevOps engineers. In a DevOps team: the person who writes the production code should write the unit test, and that person is responsible for running the unit test. The other DevOps team member who is accountable for the quality assurance writes the testing scripts to automate the functional test, and for other testing types writes the test scripts to automate those scenarios.

A third question worried about the time that writing test cases consumes.

Q: Writing test cases consumes time — do both roles require various test cases? A: The first time you write the code, definitely it will consume time — fine. The next time you write test cases for another component, you do not have to do the manual testing of the previous component because the test script is already there — you just run it. For the second component you will probably still need time to write the test script. Slowly, as the project gets mature and you are enhancing the project with a new version, from then on you do not even have to write test scripts for the previous modules — those are already there — and you do not have to do manual testing that used to consume one week, two weeks, sometimes one month of time for just completing the testing part. Since it is automated, you do not need that time, and this is how it helps push to production faster and get feedback faster.

Finally, a student asked whether a unit test is a separate activity and whether TDD is an integral part of it.

Q: Is a unit test a separate activity? Is TDD an integral part of it? A: TDD is the approach, not a type of testing. TDD is test-driven development: the approach is writing the test script first — never matter what kind of test script. Whether you write the unit test first, or you can write the functional test first, that is TDD. Generally, people tend to write the unit test first when it comes to TDD.

Exam note: A scenario-based question can be expected from this automation module. The next session will touch that part by going through last year's question paper, and there will definitely be questions on code inspection and on testing.

10.4 Continuous Code Inspection

10.4.1 What Continuous Code Inspection Is

Continuous code inspection is equivalent to constantly scanning the code. Here we would like to identify if there are any defects at the code level. It is the process of code review — when you announce a merge request, when you announce a pull request, at that time the reviewers need to review the code. That is one part. At the same time, you can automate this code review through continuous code inspection.

Why does this matter? If you refer to the white papers of software engineering — the ones on refactoring of code and on defect prediction — it has been proven that 90 percent of the time, defects can be addressed using the code inspection tool. Ninety percent of your defects can be addressed using the code inspection tool. That is why people are now moving towards having this continuous code inspection process intact with your development process.

What the tool actually does. The inspection tool reads the source code the way a compiler does, but instead of producing a program it looks for patterns known to be risky. It is the automated version of a reviewer: it checks every line of every pull request against a catalog of rules, and reports anything that looks like a defect, a risk, or a violation of the coding standard. In the deployment pipeline, this kind of validation — static code analysis, duplication and coverage analysis, and style checking — runs right inside the commit stage, before the build even finishes.

10.4.2 Code Inspection versus Testing

These two terms sound the same. Do they do the same actions? No, and the distinction is important.

Q: Does testing do the same actions as code inspection? Both terms sound the same. A: No. Testing verifies the functionality and improves the software quality. But testing is expensive if you have to go through it over and over again — it consumes time. Even automated testing is time consuming because writing the test script takes time. The cycle looks like this: you find a defect from your test script, an error is triggered, testing stops, and the team needs to fix that error first. They fix the code, and then you go through the subsequent cycle of build, unit test, and functional test. During your functional test you get a second defect, you go back and fix it. It is an ongoing job, and the more you go over and over this automated testing, the more expensive it becomes. Code inspection improves on this: code inspection finds the defect at the code level, and this helps minimize the defects during your testing, which reduces the testing effort and makes it more efficient. That is why organizations have included code inspection as their day-to-day practice. Even with automated testing it takes time to verify functionality; by resolving the defects at the code level, you will be able to test the functionality faster.

The mental model: testing checks what the program does by running it; inspection checks what the code says by reading it. Testing needs a running system, test data, and time per cycle; inspection runs over the source instantly, before anything executes. The two are not rivals — inspection removes defects cheaply, so the testing that follows is shorter and more efficient.

10.4.3 The Four Measures of Code Inspection

What are the code inspection measures you can think about? Code inspection must be well defined as per the requirements, and there are four measures:

  1. Requirements. There are two types of requirements. Functional requirements are user needs — it would be cosmetic; what kind of functionality you want on your software and how it should look is a customer requirement, a user need. Structural requirements are related to the system — that is re-engineering; you need to have that component at this level, the next component should be called by this particular component. It is a structural need, an architectural need, a system need.
  2. Runtime defects. Identify the runtime errors before the program runs — that is what we want to achieve from code inspection. Can we identify such runtime defects even before the program gets run? Examples: initialization using the value of unset data; arithmetic operations — arithmetic operations you do on signed data that can result in overflow; array and pointers — array out of bounds; null pointers. These are all runtime defects. Developers are well aware of them: once we write the code and run it after completion, we used to get such errors, and the code used to crash because of array out of bounds. Those runtime errors can be identified before the program gets run.
  3. Preventive practices. These help you avoid error-prone or confusing code. Examples: declaration; functional default arguments; access protection; code structure — analysis of your switch statements, are you using multiple switch statements; safe typing; warnings on typecast assignments and operations. These are not problems right now — they may be converted into a bug over time — and that is what preventive practices are about, identifiable with the help of continuous code inspection.
  4. Style. In-house coding standards: you follow some kind of coding standards, like style layout or naming rules and guidelines. Instead of no standard, using a proven coding standard is better for improving quality. We want continuous code inspection to even support us in understanding the coding style our organization adopts — those coding styles can be converted into rules and guidelines when you write your code, and they should be automatically analyzed by the continuous code inspection tool.

How the four measures relate. The first measure (requirements) decides what the inspection should look for — the rules come from the functional and structural needs of the system. The next two (runtime defects and preventive practices) are the actual checks: things that will crash the program, and things that are only risky today. The last measure (style) keeps the code readable and consistent for the humans who will maintain it. An inspection run is a checklist built from all four.

10.4.4 Best Practices for a Code Inspection Process

To improve your code inspection process:

  • Involve tight stakeholders. While you identify or create the processes you want to automate, involve the developer who will write the code with that particular set of tools and technology, and involve your management and your customer, to understand what kind of limitations you have in terms of automating those code inspection processes.
  • Bring the collaboration. Collaborate both your coding and your code inspection.
  • Recognize the exceptions. Where can the exceptions be? If such exceptions exist, how can you customize and remove those rules, or customize those rules in case of exceptions? In an ideal world it is not 100 percent possible that your code will be compliant to every rule according to the coding standard. Sometimes you have to write more than 40 lines in a function because you will not be able to break it down. You will come across such exceptions, and the organization should support customizing those rules and regulations — one should be identified and ready with those exceptions.
  • Document traceability. Traceability is important for audits. Capture the history of software quality and make it traceable — wherever you want, you can go back and see what has been done towards software quality. Did new lines of code increase the bugs in your code base? Are there any leakages? Is there technical debt? These things should be traceable with the help of documents.

The 40-line exception. No rule set can be followed 100 percent of the time. A function sometimes genuinely has to exceed 40 lines because it cannot be broken down further. The organization must be ready for such exceptions in advance — identify them, and support customizing or removing the offending rules so the tool does not become a blocker for legitimate code.

10.4.5 Choosing a Code Inspection Tool

If you are looking to adopt a code inspection tool — there are multiple in the market — look for those tools which will help you to automate this inspection job, which will help you to bring more collaboration into the system, and which allow you to customize the rules as per the recognized exceptions. These are the pointers one should look for when opting for tools and technology from the market.

Exam note: Three selection pointers: the tool must automate the inspection job, bring more collaboration into the system, and let you customize the rules for the recognized exceptions. As per the syllabus, SonarQube is the tool for continuous code inspection in this course — the next section shows how it applies the four measures in practice.

10.5 SonarQube: Automating Continuous Code Inspection

10.5.1 What SonarQube Does

How do you turn the four measures of code inspection into a tool a whole team uses every day? SonarQube is the answer the syllabus points to.

SonarQube's capability is to show the health of any application. It supports a highlight issue feature, which highlights any newly introduced issues in your project. SonarQube also has a quality gate: with the help of this quality gate you can fix the leak and so improve the code quality systematically. The quality gate is the best feature of SonarQube. If any bug or issue has occurred which is going beyond the threshold value, the quality gate will make sure that the project status is failed. If it is failed, the code will not be moved or pushed to any subsequent environment. The very first job the team has to do is find and fix that particular issue and then re-trigger the cycle. Only if the quality gate says the project passes with all quality levels will the code be pushed to the subsequent environments.

The health metaphor. Think of the SonarQube project page as the dashboard of a patient's chart. The leak is the code that was just added — the new lines in the latest change — and the quality gate is the doctor's checklist applied to exactly that new code. If the new code made the patient worse, the gate says failed, and the code cannot move to the next environment until the team brings it back to good health.

10.5.2 The Metrics: Bugs, Vulnerabilities, Technical Debt, Code Smells, Coverage

The SonarQube project page shows several terms. Look at each one:

  • Bugs — the number of bugs in the code.
  • Vulnerabilities — relevant to security. Do you have any vulnerability in your code? For example, you have written a non-encrypted password, a direct text password, in your code — that is one sort of vulnerability.
  • Technical debt — sometimes we write hard code instead of dynamic code; due to time constraint, or to complete a workable product, we might come across solutions which are not up to the standard. That becomes your technical debt, and you are supposed to remove it over time.
  • Code smells — nothing but duplicate lines of code, huge commands. These are the code smells in your code.
  • Coverage — code coverage means how many lines of code have been executed with the unit test. This is exactly the coverage percentage from the unit-testing topic: executed lines divided by total lines.

Reading a real SonarQube project page. In the sample project shown on the page, the overall figures were 2,600 code smells, 67 days of technical debt (SonarQube measures technical debt as the estimated time, in days, it would take to fix the code), and 11 vulnerabilities. There were about 18,000 lines of unit tests. For the new code change that was pushed: no new bugs were added; 2 new vulnerabilities were added in this particular code change; the new technical debt or new code smells were 58 — that is, 58 new code smells in the new change.

Coverage works with thresholds: you can mention a threshold value, something like "if the code coverage is lesser than 80 percent." In this case the code coverage for the new code was 87 percent and the overall coverage was 90 percent, both greater than the defined 80 percent, and that gives the quality gate a pass.

Likewise, for all these terms you can provide a particular threshold value — for example, vulnerability should not be more than 15, or it should not be graded B or C, it should always be grade A. Some kind of thresholds you can provide.

10.5.3 The Quality Gate

SonarQube enforces the quality gate to fully enforce a code quality practice across all teams. In this quality gate you can provide the rules and regulations, and even you can provide the threshold value. SonarQube's default quality gate checks what happened on the leak period, and fails if the new code got worse in this period. When you push the code and that triggers an analysis, the new lines of code are the leak; if the leak got worse, then definitely it will fail. The quality gate enforces that the code should not further move to the subsequent environment — it will stop there itself — and the team will get the feedback accordingly: the quality gate found so-and-so number of bugs, so-and-so number of issues or code smells in the code.

Put simply: the quality gate is the best way to enforce a quality policy in your organization. It defines a set of Boolean conditions based on the major thresholds against which projects are measured, and it supports multiple quality gate definitions. Written as a formula, the gate for a project passes only when every condition passes:

where is one Boolean condition — an individual threshold check — and is the logical AND. Each answers a yes/no question such as "is the new code coverage at least the threshold?" or "is the security rating no worse than the threshold grade?" The gate passes exactly when all of the conditions are true; if any one condition is false, the whole gate fails.

10.5.4 Worked Example: A Failing Quality Gate

Take the example of a project that a team has to push forward.

The project carries three conditions in its quality gate:

  1. Security rating. This project got a security rating of B, where the threshold was A. Since B is worse than A, this condition fails.
  2. New code coverage. The code coverage for the new code is 42 percent, where the threshold was that it should not be less than 50 percent. Since 42 percent is less than 50 percent, this condition fails.
  3. Duplicate lines. Duplicate lines of code should not be more than 3 percent — in this particular example there are 15 percent, which violates the rule.

The result: even if some conditions are green — say two of the three are fine but one failed — the quality gate will enforce this project as a failure project. Final answer: the project fails the gate, because with , the AND formula demands that every condition be true. Sense-check: three of three conditions must pass; only zero passed, so failure is the only possible outcome.

That is the quality gate: one failed condition fails the whole project, and the code stays out of the subsequent environment until it is fixed and re-triggered. The first job of the team is to fix the failing condition — here, raise coverage above 50 percent, bring the security rating to A, and cut duplicate lines below 3 percent — and only then push the code forward.

10.5.5 The Issues Tab

The next best feature with SonarQube is digging into issues. If you click on the issues tab, you will be able to see the highlighted issues in your project. You can actually see what the main issues are, where they are located, when they were added to your code base, and who originally introduced those issues — all of that you will be able to visualize with the issues tab. This turns the abstract numbers of the project page into an actionable list: instead of "58 code smells," you see each smell in its file, at its line, with its author and its age.

10.5.6 When to Analyze: Pull Requests versus Branch Analysis

One of the most commonly asked questions: when to analyze the source code? There are two different practices, and it totally depends on organization to organization which practice they would like to opt for.

  • Analyze the pull request. Whenever you modify the code, push the code to your remote repository, and create a pull request, automatically the continuous code inspection should get triggered and the quality gate should analyze this new code. Analyzing the pull request basically focuses on the new code.
  • Branch analysis. Each branch has the quality gate applied — the conditions apply on the new code and on the overall code. When you merge to a particular branch, SonarQube code inspection runs, and all the conditions which are there in SonarQube run against the new code and the overall code. It assigns a status: passed or failed. The example shows a master branch that is clear, a "refactor system info" branch that is failed, and other subsequent branches that are clear — branch-wise you can perform the SonarQube code analysis.
Practice What gets analyzed When it runs
Pull request analysis Only the new code in the pull request Automatically when a pull request is created
Branch analysis New code and the overall code On merge into a branch; assigns a passed or failed status per branch

Pick pull request analysis when you want fast feedback on each proposed change; pick branch analysis when you want a standing quality report per branch, including the whole history of the code on that branch.

10.5.7 Where Code Inspection Sits in the Build Process

Code inspection is an add-on process in your build. The build process flow: whenever you do a code check-in or push the code, it should trigger your continuous integration. Through continuous integration, the first job is the build process. Inside the build process the steps run in this order: first unit test, then code inspection, then build, and after the build the artifact is generated. Against those artifacts you perform the functional testing and subsequent testing. The same artifact gets pushed into the subsequent environment for further testing.

A correction worth remembering. The ordering was corrected during the discussion: unit test comes first, the artifact is generated after the build, and the functional tests run against the artifact, not before it. So the corrected order is: unit test → code inspection → build → artifact generated → further testing — with the code inspection coming in between your build process steps.

10.5.8 Integrating SonarQube with the Toolchain

Since code inspection comes in between the build process, if we are using SonarQube we need to think whether we can integrate it with other tools and technology in the DevOps tool chain. If we are able to, only then will we opt for SonarQube.

SonarQube can be integrated with build tools like Maven and Gradle, Makefile, and MSBuild and many more build tools. You can even integrate SonarQube with continuous integration tools like Bamboo, Travis CI, Jenkins, and TeamCity, and other subsequent tools and technology. So SonarQube has a wide range of integration with the multiple tools and technology that are part of your DevOps tool chain, and that is why people choose it. It is really easy to get started: download SonarQube and hit the SonarQube webpage — you will easily see the projects, the issues, the rules tab. You can even customize the rules. There are inbuilt rules basically depending on the language you are using — for Java there are code level rules, for Python there are code level rules already inbuilt, and default rules are also there. You do not have to go and write rules from scratch to perform your code inspection.

10.6 Continuous Integration

10.6.1 What Continuous Integration Is

This is the last topic as per the mid-semester examination. So far we understood source code management, we understood how to automate the build process and how to automate the other parts of the build process — unit testing, functional testing, code inspection — with the help of tools and technology. Now we are in a position to integrate it all together and understand the continuous integration practices.

The question this topic answers: how do you keep an application in a working state at every moment, instead of discovering only at the end whether all the pieces fit? The answer is a practice called continuous integration — and the exam note that matters most is that this is the final syllabus point before the mid-semester examination.

Continuous integration is the process of integrating the new code written by your developer into the mainline or master branch frequently throughout the day. As new code has been written, it should be frequently merged to the master branch, and then pushed to the production environment. Nobody is interested in trying to run the whole application until it is finished. In the current trend, people are always trying to keep their application in a working state.

That is a real shift. In the traditional way of working, the team during development spent a significant portion of time in an unstable state. We never bothered to run the code; we used to write the code base and just compile it, see whether there were compilation errors, fix those, and start writing the functionality again — but we never ran the code until and unless the full functionality was ready. With that trend, most of the time the developer used to write code on an application which was always in an unstable, unusable state. The trend has now shifted to the working state. With agile, we want every scrum — during your scrum, every sprint — to release working software, a workable item. Everybody is looking at the working state, and they would like to add the code to the working state of the application itself.

10.6.2 The Two Requirements of Continuous Integration

How do you achieve this? With continuous integration, and continuous integration has two hard requirements:

  1. Every time somebody commits any change — a new line to your code base — the entire application should get built.
  2. A comprehensive set of automated tests should run against it, to make sure the code base or your application is in a working state.

A day with continuous integration. A developer finishes a small change — say a fix to the login validation — and commits it at 10:15 a.m. The CI system immediately picks up the commit, builds the entire application (compiling every module, not just the changed file), and runs the automated tests against that build. At 10:17 the build is green: the application is in a working state with the fix inside it. The same developer commits the next small change at 11:00, and the same full build-and-test cycle runs again. Every commit between 10:15 and 5:00 p.m. gets the same treatment, so at no point during the day is the application in a state that nobody has run and nobody can vouch for. Sense-check: two events — a commit and a finished build — happen per cycle, and the cycle repeats on every commit; that is exactly what "continuous" means.

If your build or test process fails, the development team should stop there itself — whatever they are doing, their first job is to fix those problems immediately. The goal of continuous integration is that the software is always in a working state all the time, throughout the time of your project life cycle.

The working principle in simple words: finish first before start. Whatever you have in your plate, finish those things first, and then start with the next project. A broken build is the top-priority item on the whole team's plate — nothing new starts until it is fixed.

10.6.3 Prerequisites: Version Control, Automated Build, Team Agreement

What are the prerequisites to implement continuous integration? The first prerequisite is your version control, where you have your code base. What is the second?

Q: What could be the second prerequisite for continuous integration? A: The second prerequisite is an automated build process — we understood it can be done with Maven and subsequent tools. And for functional testing we understood Selenium, for code inspection we understood SonarQube. The build must be startable by a single command, so that a computer — not just a person — can run it.

The third main and important thing is the agreement of the team. And that raises the key question: what is continuous integration — is it a tool or is it a practice?

Q: Is continuous integration a tool or a practice? A: It is a practice. So if it is a practice, you need people — you need involvement of people and agreement from the people. Today the focus is on the agreement of the team.

In terms of the agreement of a team, this is more about people and culture. Continuous integration is a practice, not a tool, and it requires a degree of commitment and discipline from your development team or DevOps team, or the people involved in your team, so that they could get a benefit out of it. Everyone needs to check in small incremental changes — small changes should always be checked in frequently, pushed to the mainline — and everyone should agree that the highest priority task on the project is to fix any break in the application or any failure in the application. If people do not adopt this discipline necessary for it to work, then even if you have attempted continuous integration, you will not be able to achieve the improvement in quality you were looking for. You need focused agreement from your team, and they should adopt this discipline very seriously.

10.6.4 CI Systems: Open Source and Commercial

Continuous integration is a practice, but to automate this practice there are tools available in the market. Continuous integration systems are those tools which help us automate this job. Among open source tools you have Jenkins, Cruise Control, GitLab CI, and GitHub Actions. Among commercial tools you have ThoughtWorks, TeamCity, Bamboo, and Buildflow. CircleCI is a combination — it is open source as well as licensed; with the open source version you can run about 3,000 builds per day, that is the condition.

10.6.5 From Nightly Builds to Continuous Integration

How was it done before continuous integration? We used to do nightly builds. We used to write code the full day, and once we were done with the duty — around 5 p.m., leaving the premises by 6 or 7 p.m. — the nightly build script used to build the entire code base written by the entire team.

This strategy is not a good idea when you have a geographically dispersed team working on a common code base from different time zones. Why? The nightly build for India time is the night. But if you think about the US, they are working in their morning on the code base which was written by the Indian team, and there could be huge errors — huge runtime errors that could be part of your code base. Now your code base is unstable, unusable, and your US team members are adding code to that unstable, non-working code base. The size of the code base is increasing, and if there are any failures, isolating those code errors will be a difficult job. So the nightly build would be the worst idea for a geographically dispersed team.

Continuous integration fixes exactly this: instead of one integration attempt per day, every commit triggers its own build and test cycle, so a broken state is detected within minutes of being created — by the person who created it, in their own time zone.

10.6.6 Best Practices for Continuous Integration

The best practices that were covered:

Check in regularly. You should have frequent check-ins. Whenever you do small code changes frequently, push them to the remote repository or check into your master branch.

Create a comprehensive automated test suite. Unit testing should be automated, component test should be automated, acceptance test should be automated — whatever test suite you have, try to automate those test types with the help of subsequent tools and technology. A comprehensive automated test suite provides an extremely high level of confidence in your team members that any introduced change has not broken existing functionality, and the team will be highly confident that this particular code will even work for the production environment.

Keep the build and test process short. The standard recommendation for the automated build and test process: it should not take more than 90 seconds — 90 seconds is the ideal time of your build process. Five minutes is better; ten minutes is good. What happens if it takes more time?

Q: If the automated build process takes one hour, what will happen — what consequences can you think of? A: Bug fixes will be delayed, and the release time will be longer. From a developer's point of view: say I am writing ten lines of code, I commit it, and the build process will trigger. Meanwhile I understood I need to add a few more points to the code base — I have to wait for one hour. If the build is taking longer, you minimize your motivation to check in frequently; that motivation will come down, and people will stop pushing until the full chunk is ready. And if you are pushing code with a huge code base, again you slowly enter the traditional way of working, where you are adding new code to an application that is unstable, not in a working state.

Long builds are a silent killer of the practice. The one-hour build shows the mechanism: slow feedback delays bug fixes, lengthens the release time, and — most damaging — quietly lowers the motivation to commit frequently. Developers start hoarding their changes into one big push, and the team slowly slides back into the traditional big-bang way of working, adding new code to an application that is unstable and not in a working state.

Manage your development workspace. The local development workspace must be a replication of production. The tools and technology should be similar to the production environment, because that will bring in more confidence in your team that the code will work fine on the production environment.

The remaining best practices will be covered in the next session, along with going through last year's question paper. In closing, a student asked for a flow diagram showing how configuration management, SonarQube, Maven, Selenium, and Jenkins interrelate; the response was that a generic pipeline document will be shared — what a CI/CD pipeline generally looks like for a web application, how it happens for a mobile application, and what the CI/CD pipeline setup looks like for microservices on Kubernetes with Azure. The Selenium script will also be shared in the reference document — it was written in a basic, layman way so that it is easy to understand.

Exam Guidance Summary

  • No direct tool questions. No questions ask you to write scripts, commands, code, or pipelines for Jenkins, AWS, or Git. Questions are scenario based: given a problem, which tool chain helps solve it. For a continuous integration problem, any CI system such as Jenkins or CircleCI is an acceptable answer.
  • Jenkins scope. Jenkins is not in the mid-semester syllabus. The comprehensive examination may still carry a conceptual question — distributed versus centralized, whether it supports both.
  • Git scope. No command-writing questions. Expect conceptual questions: difference between merge and pull; difference between revert and reset.
  • Answer to the marks. A five-mark question deserves five distinct points covering the scenario; a one- or two-mark question deserves two or three lines with the point. Pages of theory unrelated to the scenario score zero.
  • Syllabus. Nine modules in the course handout; the mid-semester examination covers five and a half modules. A syllabus note will be published on the course channel.
  • Exam mode. Online, open book, on the online exam platform; the handout's "closed book" text is overridden by the online format. Soft copies from your laptop are usable; toggling between tabs may be restricted, so take printouts of deck PDFs and carry your notebooks to be safe.
  • Diagram questions. Draw and upload a snapshot (handwritten), or use the text box; mixing typed and handwritten answers per question is allowed.
  • Expected question topics. A scenario-based question from the automation module (Selenium, SonarQube); questions on code inspection and on testing. Last year's question paper is available on the course portal and will be reviewed in the next session.
  • Study order. Presentation deck first, then the recorded sessions, then the textbook if time permits. The deck plus recorded sessions is enough to clear the examination.
  • Answer in your own words. No copy-pasting from web portals or from the deck — the exam checks your understanding and your own language.
  • Books. Compile the per-session chapter references; buy one book and take printouts of the PDF chapters of the others to keep handy.
  • Quizzes. Four tutorial sessions with a quiz after each; the best two of four count. Quizzes one and two are done; quizzes three and four are mandatory. Tutorial recordings are available.

Key Industry Applications

Real-world: Jenkins, CircleCI, GitLab CI, GitHub Actions, and Cruise Control are real open-source CI systems used in industry; ThoughtWorks, TeamCity, and Bamboo are commercial options; CircleCI offers an open-source tier with roughly 3,000 builds per day.

Real-world: the 90-second / 5-minute / 10-minute build-time guidance mirrors what practitioners watch for: long builds discourage frequent commits, which quietly drags a team back to big-bang integration. Large organizations that adopted continuous integration and trunk-based development — such as the HP LaserJet firmware division with 400 developers across time zones — went from two releases a year and weeks of manual regression testing to over a hundred commits per day and regression testing measured in hours.

Real-world: Selenium is the tool most organizations pick for automating web-browser functional tests; some organizations also drive mobile application testing with it. Its four components map to real workflows: IDE for record-and-playback prototyping, the deprecated RC, WebDriver (Selenium 2) for direct browser automation, and Grid for parallel test execution across machines, browsers, and devices.

Real-world: geographically dispersed teams on shared codebases (for example India and the US time zones) are exactly why nightly builds fail and why CI — integrating and building every commit — became the industry standard.

Real-world: SonarQube quality gates are wired into real pipelines as an add-on build step: unit test, code inspection, build, artifact generation, then further testing. SonarQube integrates with Maven, Gradle, Makefile, MSBuild, and CI tools like Bamboo, Travis CI, Jenkins, and TeamCity, with inbuilt per-language rules for Java and Python.

Real-world: security ratings, vulnerability counts, technical debt, and code coverage thresholds (for example coverage not below 80 percent, vulnerability grade A) are the kind of quality policies organizations enforce with gates — a single failed condition blocks the code from moving to the next environment.

Real-world: in real DevOps teams, the person who writes the production code also writes and runs the unit tests, while the QA-accountable member writes the automation scripts for functional and other test types.

Real-world: pull-request analysis (checking only the new code) and branch analysis (checking new and overall code on merge) are the two standard ways teams schedule code inspection, and generic CI/CD pipeline patterns differ by target: web application, mobile application, and microservices on Kubernetes with Azure.

ITD Lecture 10 notes · Testing, Code Inspection, and Continuous Integration

Introduction to Devops· postgraduate· 2026-08-14

Sections Breakdown

110.1 Mid-Semester Exam: Format, Logistics, and Preparation

Exam intel: scenario-based questions with no command writing, answering to the marks, five and a half of nine modules covered, online open-book logistics, and the study plan.

210.2 Unit Testing: Testing Pieces Instead of the Whole

Testing individual components early instead of the whole system at the end: the login-page worked example, the code coverage formula, goals, benefits, and guidelines.

310.3 Automating Functional Testing with Selenium

Selenium benefits, the login-page walkthrough, finding web elements with browser developer tools, the four components, platforms, client-server architecture, the grid, and student Q&A.

410.4 Continuous Code Inspection

Constantly scanning the code for defects: the definition, inspection versus testing, the four measures, best practices, and choosing a tool.

510.5 SonarQube: Automating Continuous Code Inspection

Application health metrics, the Boolean quality gate conditions with worked examples, the issues tab, pull request versus branch analysis, and toolchain integration.

610.6 Continuous Integration

Frequently merging new code into the mainline: the two requirements, prerequisites, open source and commercial CI systems, nightly build problems, and best practices.

7Exam Guidance Summary

Consolidated exam guidance: scenario-based questions, marks-matched answers, open-book logistics, study order, own-language answers, and the quiz policy.

8Key Industry Applications

How the tools and practices map to industry: CI systems, build-time guidance, Selenium testing, SonarQube gates, DevOps test ownership, and analysis practices.

Postgraduate students of software engineering and delivery

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

Mid-Semester Exam: Format, Logistics, and Preparation

Must-know: The exam is scenario based: given a problem, recommend the tool chain that solves it; no script, command, code, or pipeline writing questions. Jenkins and CircleCI are acceptable answers for continuous integration problems.

⚠️ Top pitfall: Writing pages of theory unrelated to the scenario scores zero. Match the number of distinct scenario-relevant points to the marks of the question.

Self-check: What should you prepare first for the examination if you are short on time, and what is the minimum that is enough to clear it?

Connects to: Section 10.3, Section 10.5, Section 10.6

Unit Testing: Testing Pieces Instead of the Whole

Must-know: Unit testing tests each component individually, at least once, written and run by the developers themselves. It changes the timing of error discovery: errors are found early, isolated, and cheap to fix, and the tests form a regression net and living documentation.

⚠️ Top pitfall: Testing the whole system only at the end lets errors go undetected until the end customer reports them in production, and isolating which source code triggered the bug becomes difficult.

Self-check: If the login module has 500 lines of production code and the unit tests execute 385 of them, what is the code coverage?

Connects to: Section 10.3, Section 10.5, Section 10.6

Automating Functional Testing with Selenium

Must-know: Selenium automates browser interaction: identify web elements (ID/XPath), pass values, perform actions. WebDriver (Selenium 2) is the actively used component; Grid parallelizes one script across machines, browsers, and devices via a hub. In a DevOps team the person who writes the production code writes and runs the unit test, while the QA-accountable member writes the automation scripts.

⚠️ Top pitfall: Jumping straight into Selenium Grid is not easy — learn Selenium first with small scripts on public sites, then read the official documents. Also, do not think of TDD as a type of testing: it is the approach of writing the test script first.

Self-check: Which component of Selenium is used to run the same test script in parallel across different machines and browsers, and what is its purpose?

Connects to: Section 10.2, Section 10.5, Section 10.6

Continuous Code Inspection

Must-know: Continuous code inspection is constantly scanning the code to identify defects at the code level; it automates code review. White papers on refactoring and defect prediction say 90 percent of defects can be addressed with code inspection tools. The four measures are requirements, runtime defects, preventive practices, and style.

⚠️ Top pitfall: Confusing testing with code inspection: testing verifies functionality by running the program and is expensive when repeated; code inspection finds the defect at the code level before it runs and makes the testing that follows faster.

Self-check: Name the four measures of code inspection and give one example of a runtime defect that can be caught before the program runs.

Connects to: Section 10.2, Section 10.5

SonarQube: Automating Continuous Code Inspection

Must-know: The quality gate is a set of Boolean conditions on thresholds; the project passes only when every condition passes (pass = C1 AND C2 AND ... AND Cn). One failed condition fails the whole project and blocks the code from the next environment until fixed and re-triggered. The metrics are bugs, vulnerabilities, technical debt, code smells, and coverage.

⚠️ Top pitfall: Thinking a single green condition saves the project: with AND logic, even two of three green conditions fail the gate (e.g., rating B versus threshold A, coverage 42 percent versus 50, duplicates 15 percent versus 3).

Self-check: In a sample SonarQube project page with 87 percent new-code coverage and 90 percent overall coverage against an 80 percent threshold, does the coverage condition pass?

Connects to: Section 10.2, Section 10.4, Section 10.6

Continuous Integration

Must-know: Continuous integration is a practice, not a tool: on every commit the entire application is built and a comprehensive set of automated tests runs against it; if the build or tests fail, fixing them is the team's first job. Prerequisites: version control, an automated build process, and the agreement of the team. The ideal build time is about 90 seconds, 5 minutes is better, 10 minutes is good.

⚠️ Top pitfall: Nightly builds fail for geographically dispersed teams — the next time zone builds and commits on an unstable code base. Long builds (e.g., one hour) delay fixes, lengthen release time, kill the motivation to commit frequently, and drag the team back to big-bang integration.

Self-check: Why is the nightly build the worst idea for a geographically dispersed team, and what are the two hard requirements of continuous integration?

Connects to: Section 10.2, Section 10.3, Section 10.5

Exam Guidance Summary

Must-know: The mid-semester examination is scenario based with no script or command writing; a five-mark question needs five distinct scenario-relevant points; five and a half of the nine modules are covered; the exam is online and open book.

⚠️ Top pitfall: Copy-pasting answers from web portals or the deck — the exam checks your own language and understanding, and unrelated theory scores zero.

Self-check: Which two quizzes are mandatory and how many of the four quizzes count toward your score?

Connects to: Section 10.1, Section 10.3, Section 10.5, Section 10.6

Key Industry Applications

Must-know: CI systems in industry split into open source (Jenkins, Cruise Control, GitLab CI, GitHub Actions) and commercial (ThoughtWorks, TeamCity, Bamboo, Buildflow), with CircleCI as an open-source-and-licensed hybrid; SonarQube quality gates run as an add-on step in real build pipelines.

⚠️ Top pitfall: Adopting tools without the practice: continuous integration only works when the team agrees to frequent small commits and treats a broken build as the top priority.

Self-check: Why did geographically dispersed teams such as the HP LaserJet firmware division move from nightly builds to continuous integration?

Connects to: Section 10.3, Section 10.5, Section 10.6

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.