Introduction to Computing

Chapter 7
Software Engineering and Development Practice

Bachelor Program in Mechatronics Engineering
Introduction to Computing   •   Bachelor

Software Engineering and Development Practice

Introduction

Software is not merely a collection of instructions that makes a computer produce an output. In engineering contexts, software is a designed artifact that must satisfy requirements, operate safely, remain understandable, and be modified over time. A mechatronics system may combine sensors, actuators, embedded controllers, communication networks, mechanical elements, and supervisory software. Failure in any software component can therefore cause incorrect measurements, unsafe motion, production loss, or expensive maintenance.

Software engineering is the systematic application of engineering principles to the specification, design, implementation, verification, deployment, operation, and maintenance of software. This chapter develops a practical foundation for producing maintainable software. It connects requirements analysis, design models, coding standards, documentation, debugging, testing, version control, collaborative repositories, agile development, and continuous integration.

The central idea is that quality is created throughout development. Testing cannot compensate for unclear requirements, and version control cannot compensate for poor design. Effective development practice combines technical discipline with communication, review, risk management, and ethical responsibility.

Learning Objectives

By the end of this chapter, a student should be able to:

  1. Explain the purpose and activities of software engineering.
  2. Convert stakeholder needs into testable software requirements.
  3. Use basic models to communicate software structure and behavior.
  4. Apply coding standards, modular design, and documentation practices.
  5. Distinguish debugging from testing and select appropriate techniques.
  6. Use version control and collaborative repositories responsibly.
  7. Explain agile methods, iteration, and continuous integration.
  8. Evaluate development decisions in relation to maintainability, safety, security, and ethics.
  9. Plan a small software project using an integrated engineering workflow.

1. Software Engineering as an Engineering Discipline

A software product passes through a life cycle. Typical activities include requirements elicitation, analysis, design, implementation, verification, deployment, operation, and maintenance. These activities are not always strictly sequential. Modern projects revisit earlier decisions as new information becomes available.

The major software life-cycle approaches include:

ApproachMain characteristicStrengthLimitation
WaterfallPhases are largely completed in sequenceClear documentation and milestonesChanges late in the project are costly
IterativeThe product is refined through repeated cyclesEarly learning and gradual improvementRequires disciplined planning between iterations
IncrementalFunctionality is delivered in usable portionsValue is delivered earlyIntegration between increments can be difficult
AgileShort cycles, feedback, and adaptive planningResponds well to changing requirementsCan fail without technical discipline
V-modelDevelopment activities are paired with test activitiesEmphasizes verification and validationLess flexible when requirements change

Software quality has several dimensions. Functional suitability asks whether the system performs the required tasks. Reliability concerns consistent operation under stated conditions. Usability concerns learnability and error prevention. Maintainability concerns the cost and safety of modifying the system. Security concerns protection against unauthorized access, alteration, or disclosure. Performance concerns response time, throughput, memory, and energy use.

These qualities can conflict. For example, extensive logging may improve diagnosability but consume storage and processing capacity. Strong security controls may increase complexity. A professional engineer makes such trade-offs explicit rather than assuming that one quality criterion can be maximized independently.

2. Requirements Engineering

Requirements describe what a system must do and the constraints under which it must operate. Requirements engineering includes elicitation, analysis, specification, validation, prioritization, and management.

2.1 Stakeholders and elicitation

A stakeholder is a person or organization affected by the system or able to influence it. In a robotic cell, stakeholders may include an operator, maintenance technician, safety engineer, production manager, customer, regulator, and software developer. Each may express different needs. Operators may emphasize clear alarms, while maintenance staff may require diagnostic logs.

Common elicitation techniques include interviews, observation, workshops, document analysis, prototypes, questionnaires, and analysis of existing systems. A requirement should be based on an identifiable need rather than an assumed implementation.

2.2 Functional and non-functional requirements

A functional requirement specifies a service or behavior. For example: “The controller shall record motor temperature once every second.” A non-functional requirement specifies a quality attribute or constraint: “The temperature record shall be available for inspection within two seconds of a request.”

Requirements should be:

  • correct and traceable to a stakeholder need;
  • unambiguous and understandable;
  • complete within the defined scope;
  • consistent with other requirements;
  • feasible with available resources;
  • verifiable through inspection, analysis, demonstration, or test;
  • prioritized according to value and risk.

A useful requirement pattern is: “The system shall [observable behavior] under [specified condition] with [measurable criterion].” Terms such as “fast,” “user-friendly,” and “adequate” should be replaced by measurable criteria.

2.3 Use cases and user stories

A use case describes interaction between an actor and a system to achieve a goal. For example, an operator may select “Start calibration,” after which the system checks safety interlocks, moves the mechanism to a reference position, records sensor values, and reports completion or failure.

A user story is a short agile expression of value: “As a maintenance technician, I want to export fault history so that I can identify recurring failures.” A story is not a complete specification; it should be supported by acceptance criteria. One criterion might state: “Given a selected date range, the system exports all faults in chronological order as a comma-separated file.”

2.4 Traceability

Traceability links requirements to design elements, source code, tests, and operational evidence. A traceability matrix can reveal requirements with no test and tests with no corresponding requirement. This is especially important in safety-related or regulated systems.

A simple coverage measure may be expressed as:

Requirement coverage = (Number of requirements linked to at least one test ÷ Total number of requirements) × 100%

This measure is useful only when “linked” means meaningfully verified. A high percentage does not prove that the tests are adequate, and it does not measure code quality. It should therefore be interpreted with test results, defect records, and review evidence.

3. Design Models and Architecture

Design translates requirements into a structure that can be implemented and evaluated. Architecture identifies major components and their relationships; detailed design specifies interfaces, data structures, algorithms, and error handling.

A common embedded architecture separates:

  1. Hardware abstraction: drivers for sensors, actuators, timers, and communication interfaces.
  2. Services: logging, configuration, communication, diagnostics, and data storage.
  3. Application logic: control sequences, state machines, and domain rules.
  4. User interface or supervisory layer: displays, commands, and alarms.

Separation of concerns reduces the effect of change. For example, replacing a temperature sensor should ideally require changes in a driver and configuration, not in every application function that uses temperature.

3.1 Models for communication

A context diagram shows the system boundary and external actors. A component diagram shows major software units and dependencies. A sequence diagram shows messages over time. A state-machine model represents event-driven behavior through states and transitions.

For a conveyor controller, states might include Stopped, Starting, Running, and Faulted. A transition from Running to Faulted may occur when an emergency-stop signal is detected. The model should define what happens on entry to a state, what events cause transitions, and what outputs are permitted. State machines are particularly valuable when safety behavior depends on sequences of events.

3.2 Modularity and interfaces

A module should have a focused responsibility and a small, clear interface. High cohesion means that the responsibilities within a module belong together. Low coupling means that modules depend on one another as little as practical.

An interface should define inputs, outputs, units, valid ranges, timing assumptions, error behavior, and ownership of data. For example, a function named set_speed(1200) is unsafe if the unit—revolutions per minute, pulses per second, or a percentage—is not documented. Interfaces should also specify whether a function blocks, whether it is thread-safe, and what happens when a device is unavailable.

4. Coding Standards and Maintainable Implementation

Coding standards are agreed rules for naming, formatting, structure, comments, error handling, and prohibited practices. Their purpose is not cosmetic uniformity. Consistent code reduces cognitive load, makes defects easier to detect, and allows reviewers to focus on behavior.

Good practice includes:

  • use names that express intent;
  • keep functions small enough to understand and test;
  • avoid duplicated logic;
  • make units and coordinate systems explicit;
  • validate input at system boundaries;
  • handle errors deliberately rather than silently;
  • avoid unexplained constants by using named configuration values;
  • limit global mutable state;
  • use automated formatting and static analysis where available;
  • treat compiler warnings as issues to investigate.

A comment should explain why a non-obvious decision exists, not restate the code. For example, “Use a 50 ms debounce interval because the selected switch produces contact bounce during this range” is more valuable than “Set delay to 50.” Comments must be maintained when the implementation changes.

Defensive programming is important in mechatronics. Sensor values should be checked for range, plausibility, freshness, and communication status. A missing sensor packet should not automatically be interpreted as a safe zero. The system should enter a defined fault response, which may include stopping motion, raising an alarm, and preserving diagnostic information.

5. Documentation

Documentation serves different audiences. A requirements document supports agreement and verification. Architecture documentation supports design decisions. API documentation supports programmers. User and maintenance manuals support operation. Release notes explain changes and known limitations.

Useful documentation should answer:

  • What problem does the component solve?
  • What are its inputs, outputs, assumptions, and failure modes?
  • How is it built, tested, configured, and deployed?
  • What decisions were made and why?
  • Which requirements and tests are related to it?

Documentation should be versioned with the product where practical. An outdated manual can be more dangerous than no manual because users may trust incorrect instructions.

6. Debugging and Testing

Testing is the planned evaluation of software to reveal defects or provide evidence that specified behavior has been met. Debugging is the process of locating, understanding, and correcting the cause of a failure. A test may reveal that a temperature alarm is incorrect; debugging investigates whether the cause is a conversion error, stale data, incorrect threshold, or display defect.

6.1 Levels of testing

  • Unit testing: evaluates a function or small module in isolation.
  • Integration testing: evaluates interactions between modules or devices.
  • System testing: evaluates the complete system against requirements.
  • Acceptance testing: determines whether the stakeholder or customer accepts the system.
  • Regression testing: repeats tests after changes to detect unintended effects.

6.2 Test design

Black-box testing derives tests from requirements without relying on internal implementation. Boundary-value analysis tests values at, just below, and just above limits. Equivalence partitioning divides inputs into groups expected to behave similarly. Decision-table testing is useful when outputs depend on combinations of conditions.

White-box techniques use implementation structure. Statement coverage asks whether statements have executed; branch coverage asks whether decision outcomes have executed. Coverage is evidence of exercised code, not proof of correctness. A test suite can achieve high coverage while failing to check important results.

A good test has a clear precondition, input, expected result, and pass/fail rule. Test data should include normal operation, invalid inputs, communication loss, timing variation, power interruption where relevant, and recovery from faults.

6.3 Debugging method

A disciplined debugging process is:

  1. Reproduce the failure reliably.
  2. Record conditions, inputs, software version, and hardware configuration.
  3. Form a specific hypothesis.
  4. Collect evidence using logs, assertions, traces, or instrumentation.
  5. Change one relevant factor at a time.
  6. Identify the root cause rather than only suppressing the symptom.
  7. Correct the defect and add a regression test.
  8. Review related code for similar defects.

Logs should contain timestamps, severity, component identity, event information, and relevant identifiers. Sensitive information must not be logged unnecessarily.

7. Version Control and Collaborative Repositories

Version control records changes to files and enables recovery, comparison, branching, review, and coordinated work. In a distributed system such as Git, each clone can contain repository history. A commit should represent a coherent, tested change and should have a meaningful message.

A practical workflow is:

  1. Update the local main branch.
  2. Create a short-lived feature branch.
  3. Implement a focused change.
  4. Run formatting, static checks, and tests locally.
  5. Commit with a clear message.
  6. Push the branch to a shared repository.
  7. Open a pull request for review.
  8. Resolve comments and automated failures.
  9. Merge only when required checks and approvals are complete.

Branches are not a substitute for communication. Long-lived branches increase integration risk. Pull requests should explain purpose, design consequences, tests performed, configuration changes, and known limitations.

Repository governance should define protected branches, review requirements, issue tracking, release tags, access permissions, and backup policy. Secrets such as passwords, private keys, and tokens must not be committed. Large generated files and build artifacts should normally be excluded or stored using an appropriate artifact system.

8. Agile Methods and Iterative Development

Agile development emphasizes delivering useful increments, obtaining feedback, and adapting plans. Scrum commonly uses a product backlog, sprint planning, a time-limited sprint, daily coordination, review, and retrospective. Kanban emphasizes visualizing work, limiting work in progress, and improving flow.

Agile does not mean “no documentation” or “no planning.” It means planning at an appropriate level of detail and revising plans as evidence changes. A team should maintain a clear product goal, acceptance criteria, technical quality criteria, and a definition of done. A feature is not done merely because code exists; it may also require tests, review, documentation, integration, and deployable configuration.

Agile has limitations. Frequent requirement changes can create architectural inconsistency. Pressure to deliver visible features can cause technical debt. Self-organizing teams still need engineering leadership, safety review, and governance. In a safety-critical context, iteration must coexist with hazard analysis, traceability, formal approvals, and controlled change.

9. Continuous Integration and Delivery

Continuous integration (CI) is the frequent integration of changes into a shared codebase followed by automated building and testing. A typical pipeline is:

Commit → Build → Static analysis → Unit tests → Integration tests → Package → Review or deployment

A useful CI pipeline should be repeatable, fast enough to support frequent feedback, and sufficiently isolated from a developer’s machine. It should report failures clearly and preserve test artifacts such as logs and coverage reports.

Continuous delivery means that software is kept in a deployable state, while continuous deployment automatically releases qualifying changes. These are distinct practices. A team may use continuous delivery with a manual approval for production deployment.

CI does not eliminate defects. It detects certain classes of problems early. It is ineffective if tests are unreliable, important hardware behavior is never simulated or tested on representative hardware, or teams routinely ignore failed builds. Build reproducibility, dependency management, access control, and secure pipeline configuration are essential.

10. Integrated Case Study: Conveyor Monitoring Controller

The following is an illustrative case, not a report of a particular commercial project.

Background

A small manufacturing cell uses a motor-driven conveyor. An embedded controller reads speed and temperature sensors, controls the motor drive, displays status, and sends alarms to a supervisory computer.

Problem

The initial prototype was written by one developer. It worked during demonstrations but suffered from intermittent false alarms, unclear sensor units, difficult configuration, and unsafe behavior when communication with the temperature sensor was interrupted. Several changes were made directly on a shared computer, so the team could not reliably identify which version was installed.

Analysis

The team first interviewed operators and maintenance staff and reviewed hazard information. The principal requirements were:

  • the conveyor shall stop when an emergency-stop input is active;
  • speed shall be displayed in revolutions per minute with a stated tolerance;
  • a missing temperature update shall generate a fault within a defined time;
  • all faults shall be timestamped and retained until acknowledged;
  • every released software version shall be identifiable and reproducible.

The team created a context diagram, a state machine, and an interface specification. The state machine included Stopped, Starting, Running, and Faulted. Sensor input was separated from control logic through a hardware-abstraction interface.

Approach and solution

The team adopted a repository with protected main branch, feature branches, pull requests, and mandatory CI checks. Coding standards required explicit units in names or interfaces, such as speed_rpm and temperature_C. Unit tests covered conversion functions, threshold logic, and stale-data detection. Integration tests used a simulated sensor and later representative hardware.

The stale-data rule was specified as a requirement rather than hidden in code: if no valid temperature sample arrives within the permitted interval, the controller enters Faulted and prevents automatic restart. A review also identified that an old prototype treated a missing value as zero, which could mask overheating.

The CI pipeline compiled the firmware, ran static analysis, executed unit tests, packaged the build, and recorded the commit identifier. A release checklist required successful hardware tests, updated configuration documentation, and confirmation that emergency-stop behavior had been verified.

Outcome

False alarms were reduced after the team corrected a unit-conversion defect and separated sensor validity from sensor value. Maintenance staff could identify the installed version and export fault history. More importantly, the system had an explicit and reviewable response to missing sensor data. The team accepted that automated tests could not replace physical safety validation; emergency-stop behavior remained subject to hardware-in-the-loop and operational testing.

Learning points

The case demonstrates that maintainability is a system property. It emerged from clear requirements, explicit interfaces, state modeling, tests, repository governance, and deployment discipline—not from a single programming technique. It also shows why safety assumptions must be documented and tested under abnormal conditions.

11. Professional, Ethical, and Governance Considerations

Software engineers have responsibilities beyond satisfying a customer’s immediate request. They must communicate risks honestly, protect confidential data, respect licenses, and avoid releasing software known to create unreasonable danger. Safety claims should be supported by evidence rather than confidence or schedule pressure.

Security should be considered throughout the life cycle. Threat modeling can identify assets, trust boundaries, attack surfaces, and likely misuse. Secure practices include least-privilege access, dependency updates, input validation, secure secret handling, authenticated communication where required, and timely vulnerability response.

Artificial intelligence tools can assist with code suggestions, test generation, documentation, and defect investigation. However, generated code may contain security defects, licensing problems, incorrect assumptions, or unsuitable hardware interactions. Engineers remain responsible for reviewing, testing, documenting, and authorizing the result. Proprietary source code and personal data should not be submitted to tools without permission and appropriate controls.

12. Best-Practice Checklist

Before a small software component is released, ask:

  • Are its requirements clear, prioritized, and testable?
  • Are assumptions, units, limits, and failure modes documented?
  • Is the design modular with defined interfaces?
  • Does the code follow the team’s standards?
  • Are normal, boundary, invalid, and fault conditions tested?
  • Has a reviewer examined the change?
  • Is the change recorded in version control?
  • Does the CI pipeline build and test it reproducibly?
  • Can the release be traced to requirements, tests, and a commit?
  • Have safety, security, privacy, licensing, and operational consequences been considered?

Chapter Summary

Software engineering applies systematic engineering principles to the complete life cycle of software. Maintainable software begins with stakeholder-centered, testable requirements and is supported by architectural models, modular interfaces, coding standards, meaningful documentation, and explicit error handling. Testing provides evidence about behavior, while debugging locates and removes causes of failure. Version control, code review, and collaborative repositories make changes traceable and reduce coordination risk. Agile methods support iterative learning but do not remove the need for planning, documentation, safety analysis, or governance. Continuous integration provides rapid feedback through automated builds and tests, although it cannot replace representative hardware testing or professional judgment. In mechatronics, the consequences of software failure make traceability, secure practice, fault response, and ethical responsibility essential.

Key Terms

Software engineering: The disciplined application of engineering principles to software development and maintenance.

Requirement: A needed capability, condition, or constraint of a system.

Stakeholder: A person or organization affected by or able to influence a system.

Functional requirement: A required service, behavior, or operation.

Non-functional requirement: A quality attribute or constraint on the system.

Traceability: The ability to link requirements, design, implementation, tests, and releases.

Architecture: The major structure of a system and its components and relationships.

Cohesion: The degree to which responsibilities within a module belong together.

Coupling: The degree of dependency between modules.

Coding standard: Agreed rules for producing consistent and maintainable code.

Debugging: Locating and correcting the cause of a software failure.

Unit testing: Testing an individual function or small component in isolation.

Regression testing: Repeating tests after change to detect unintended effects.

Version control: A system for recording, comparing, and managing changes to files.

Pull request: A proposed repository change submitted for review and integration.

Agile: An iterative approach emphasizing feedback, collaboration, and adaptation.

Continuous integration: Frequent integration accompanied by automated build and test activities.

Technical debt: Future cost created by expedient choices that make change or maintenance harder.

Defensive programming: Designing software to detect, contain, and safely handle invalid or unexpected conditions.

Review Questions

Short Answer Questions

  1. Distinguish a functional requirement from a non-functional requirement and give one example of each.
  2. Why are explicit interfaces important in modular software?
  3. What is the difference between testing and debugging?
  4. State two benefits of version control.
  5. What is the purpose of continuous integration?

Long Answer Questions

  1. Explain the stages of requirements engineering and discuss how traceability supports verification.
  2. Describe an architecture for an embedded mechatronics controller and explain the value of separating hardware abstraction from application logic.
  3. Compare unit, integration, system, acceptance, and regression testing.
  4. Explain how coding standards, documentation, and code review contribute to maintainability.
  5. Discuss the strengths and limitations of agile development in a safety-related mechatronics project.

Analytical / Application Questions

  1. A motor controller interprets a missing temperature message as 0 °C. Analyze the risks and propose a safer requirement, design change, and test strategy.
  2. A team has frequent merge conflicts and regularly ignores failed CI builds. Diagnose likely process and technical causes and recommend a staged improvement plan.
  3. Design a small state model for a conveyor with Stopped, Starting, Running, and Faulted states. Specify at least three events, permitted transitions, and the safety response to an emergency-stop signal.

Multiple Choice Questions with Answers

Question 1

Which statement best describes a non-functional requirement?

A. The controller shall record temperature every second.

B. The operator shall acknowledge an alarm.

C. The system shall respond to an alarm request within two seconds.

D. The motor shall enter the starting state.

Correct Answer: C. The system shall respond to an alarm request within two seconds.

Question 2

What is the primary purpose of traceability?

A. To eliminate the need for testing

B. To link requirements with design, implementation, and tests

C. To make source code execute faster

D. To prevent all requirements from changing

Correct Answer: B. To link requirements with design, implementation, and tests

Question 3

Which design property means that a module has a focused and related set of responsibilities?

A. High cohesion

B. High duplication

C. Low readability

D. Tight formatting

Correct Answer: A. High cohesion

Question 4

What is the main distinction between debugging and testing?

A. Testing changes code, whereas debugging writes requirements

B. Testing reveals failures or provides evidence; debugging seeks and corrects causes

C. Testing is manual, whereas debugging is always automated

D. Testing occurs only after deployment

Correct Answer: B. Testing reveals failures or provides evidence; debugging seeks and corrects causes

Question 5

Which practice is most appropriate for a coherent repository change?

A. Commit unrelated features together

B. Commit a focused, tested change with a meaningful message

C. Store passwords in the repository for convenience

D. Edit the protected main branch without review

Correct Answer: B. Commit a focused, tested change with a meaningful message

Question 6

Which testing technique focuses on values at, just below, and just above an input limit?

A. Boundary-value analysis

B. Code formatting

C. Load balancing

D. Version tagging

Correct Answer: A. Boundary-value analysis

Question 7

What does continuous integration normally include?

A. Frequent integration followed by automated building and testing

B. Annual integration after all development ends

C. Manual copying of files between computers

D. Deployment without verification

Correct Answer: A. Frequent integration followed by automated building and testing

Question 8

In the illustrative conveyor case, why should missing sensor data not be treated as zero?

A. Zero is always outside the numeric range

B. It can hide a communication or sensor failure and create an unsafe interpretation

C. It makes the program impossible to compile

D. It prevents version control from working

Correct Answer: B. It can hide a communication or sensor failure and create an unsafe interpretation

Question 9

Which statement about code coverage is correct?

A. High coverage proves that software is correct

B. Coverage measures exercised code and is useful evidence but not proof of correctness

C. Coverage is unrelated to testing

D. Coverage can only be measured for hardware

Correct Answer: B. Coverage measures exercised code and is useful evidence but not proof of correctness

Question 10

Which statement about AI-generated code is professionally appropriate?

A. It never needs review if it compiles

B. It should replace safety testing

C. It may assist development, but engineers must review, test, and authorize its use

D. It can always be used without considering confidentiality

Correct Answer: C. It may assist development, but engineers must review, test, and authorize its use

Introduction to Computing
Chapter 7 of 15