1. Software Engineering Process Models
Software engineering typically refers to a regimented and procedural methodology for developing software. As software has gotten more complex and team sizes have grown, various software engineering process models have evolved to encourage efficient development that ensures quality, follows timelines, and meets user expectations.
Figure 1. National Instruments offers a number of tools and add-ons to improve and automate common software engineering practices.
A process model prescribes specific phases and tasks to be completed during the development process. Each phase effectively provides a checklist of items that need to be completed before moving on to the next step in the development process. By following a process model for development, you can greatly increase your team’s ability to achieve the following:
- Deliver high-quality, reliable software
- Meet deadlines and complete each phase in a timely manner
- Demonstrate compliance with regulatory standards
- Win development bids requiring structured development practices
- Ensure product performs functionality expected by customer
- Generate documentation that simplifies maintenance and long-term support
There are several software engineering process models, including waterfall, spiral, and agile. They have all evolved to fulfill different needs and are generally accepted as having different use cases and associated benefits. However, they all share several common components or phases, such as configuration management, requirements gathering, architecture, development, testing, and deployment.
2. Software Configuration Management
Software configuration management (SCM) is an integral part of the software engineering process. SCM typically refers to tools for managing source code, developers, bugs, and the overall project status.
Many developers have experienced the frustration of unmanaged environments, where people overwrite each other’s changes or are unable to track revisions. Managing a large number of files or multiple developers is a challenge in any language. In fact, it’s often a challenge to manage an application even if it’s just one developer working on a small to medium application. Large development projects rely on configuration management tools to satisfy the following goals:
- Define a central repository of code
- Manage multiple developers
- Detect and resolve code collisions
- Track behavioral changes
- Identify changes and the people who made them
- Ensure everyone has the latest copy of code
- Back up old code versions
- Manage all files, not just source code
Perhaps the most important and commonly known SCM tool is source code control (SCC). However, in addition to many third-party SCC tools, the LabVIEW development environment features additional tools designed to help with these goals.
Figure 2. Source code control helps you manage files and track changes in team-based development environments.
Establishing guidelines for storing and managing files requires foresight into the application structure, the division of functionality, and the types of files beyond source code that will be important to track. Devote time to dividing the functionality among code, working with developers on file storage locations, and determining the additional files or resources developers need to work effectively.
3. Software Requirements Gathering and Management
Most engineering projects start with high-level specifications, followed by the definition of more detailed specifications as the project progresses. Specifications contain technical and procedural requirements that guide the product through each engineering phase. In addition, working documents, such as hardware schematics, simulation models, software source code, and test specifications and procedures, must adhere to and cover the requirements defined by the specifications.
Requirements gathering is important to ensure that you and your customer agree on the application's functionality. The granularity of the documents directly depends on the needs of your application and the criticality of it. For mission-critical systems, it’s typical to define the requirements for individual modules of code, code units, and even the tests for those units. Part of this process requires reaching an agreement on the expected behavior and how the system should perform when it receives anomalous or incorrect input.
Figure 3. NI Requirements Gateway works with industry-standard tools for requirements management and development environments such as LabVIEW and NI TestStand.
After developers gather requirements, they must document and organize requirement information and guarantee that the specifications are properly implemented. To document requirements, you can use common applications such as word processing or spreadsheet software. If you need more robust documentation, you can use requirements management tools such as Telelogic DOORS. To provide traceability between requirements and LabVIEW VIs, you can use NI Requirements Gateway requirements management and traceability software.
4. Application Architecture
If you are working on a large project with multiple developers, then your application architecture should include an understanding of how work is distributed and divided. Any large project has several clearly distinguished areas. One team may work with the network connectivity functionality, while another group may focus on the user interface. Establishing APIs is key for teams to know the best way to communicate with other components of the application.
National Instruments provides comprehensive support systems, called reference architectures, for those wanting to create a domain-specific application. The interactive reference architectures combine high-level application and system information, detailed technical documents, and a purchasing mechanism that bundles the entire system in just a few clicks. Now you can more easily find relevant content on the Web to simplify your test and measurement process, from information search to system setup.
5. Debugging and Code Reviews
Debugging capabilities are key to a development environment, and LabVIEW has comparable debugging tools to those found in text-based programming languages as well as tools unique to graphical programming languages. These debugging tools include the following:
- Execution highlighting, which shows the movement of data on the block diagram from one node to another using bubbles that move along the wires
- Single-stepping, which steps through a VI and shows each action of the VI on the block diagram as the VI runs
- Breakpoints, which you can place on a VI, node, or wire on the block diagram to pause execution at that location
- Probe Watch Window, which displays intermediate values on a wire as a VI runs
You can also disable entire sections of graphical code in a method analogous to commenting out code in a text-based programming language. Disabling parts of the code without rendering the entire program inoperative is a valuable troubleshooting technique for dealing with nonfunctional or faulty code. LabVIEW provides this functionality through the Diagram Disable Structure (Figure 4). Each Diagram Disable Structure contains two or more frames – at least one frame contains disabled code, which is wholly ignored by the LabVIEW compiler and not executed when the VI runs. A single frame can hold code that executes when the VI runs.
Identifying the source and fixing the cause of unexpected or undesirable behavior in software can be a tedious, time-consuming, and expensive task for developers. Even code that is syntactically correct and functionally complete is often still contaminated with problems such as memory leaks or daemon tasks that can impact performance or lead to incorrect behavior. These oversights can be difficult to reproduce and even more difficult to locate, especially in large, complex applications.
Figure 4. The LabVIEW Desktop Execution Trace Toolkit provides low-level details to help you debug large applications.
Problems such as memory leaks can have costly consequences for systems that are required to sustain operation for extended periods of time or for software that has been released to a customer. If software that needs debugging has been deployed and the LabVIEW development environment is not installed on the current machine, it may be beneficial to perform dynamic analysis of the code with the LabVIEW Desktop Execution Trace Toolkit over the network. For deployed systems, even if the development environment is available, it may be impractical or difficult to locally troubleshoot or profile the execution of a running system.
A code review is an important and common practice for software engineers seeking to mitigate the risk of unforeseen problems, identify the cause of bugs that are difficult to find, align the styles of multiple developers, and demonstrate that the code works. These reviews are an opportunity for a team of qualified individuals to scrutinize the logic of the developer and analyze the performance of the software.
The idea behind a code review is that having another set of eyes look at your code can help you find problems, but, in fact, most issues discovered during a code review are identified by the developer while explaining how everything works.
Once you feel the code is ready to be reviewed, meaning you think it is finished, you have to choose your reviewer. This is an important consideration because you need to choose someone who understands LabVIEW and can give constructive, sound feedback. It is not effective to choose a reviewer who understands only C because too much time is spent explaining the principles behind LabVIEW.
Figure 5. Use the LabVIEW Unit Test Framework Toolkit for automated regression testing and graphical code validation.
Manual reviews can quickly prove to be time- and cost-prohibitive for large applications; therefore, tools for static code analysis, such as the LabVIEW VI Analyzer Toolkit, are typically used to examine source code and proactively seek out potential problems. Once you have identified problems, dynamic code analysis tools, such as the LabVIEW Desktop Execution Trace Toolkit, are valuable for gaining low-level insight into the execution of code and helping developers locate the cause.
6. Validation and Testing
As a developer, you know when something is broken because it does not run. But proving to someone else or some external authority that something works correctly is a far more difficult task. The audience for this type of demonstration varies, but it can be the customer, a quality assurance group, or even a regulatory agency such as the FDA or FAA.
Testing and debugging software has always been an inseparable part of the development process, but now you can use automated tools such as the LabVIEW Unit Test Framework Toolkit to address the challenge of testing complex software. Automating this process reduces the amount of time you spend performing tests and enables more exhaustive testing. This not only helps to ensure you produce the highest-quality software possible, but it also saves money by helping you catch problems earlier and reducing the amount of time you spend performing these tests.
Functional validation and testing of code is a well-recognized part of the software engineering process and standard practice for anyone who has to "prove it works." Proving software works is more complex than merely showing that the application runs; you must validate that it works correctly. This task requires documentation and test results that demonstrate that the application behaves exactly in the way it was designed – evidence that may be required by the customer, a quality assurance group, or regulatory authorities, for example.
Large projects typically augment manual procedures with tools such as the LabVIEW Unit Test Framework Toolkit to automate and improve this process. Automation mitigates the risk of undetected errors, reduces costs by detecting problems early, and saves time by keeping developers focused on the task of writing the software instead of performing the tests themselves.
7. Deploying End-Use, Professional Applications
Many applications require frequent compilation into an executable (.exe) or a dynamic link library (.dll). An application may require building the source code into an executable every night or every 10 minutes.
For large software vendors, it is common to combine programmatic checking out of files with programmatic unit testing as well as programmatic building. This enables nightly build practices that reduce the amount of time they spend manually building code and increases the likelihood that they find deployment-related problems early in the process.
When the LabVIEW project was introduced in LabVIEW 8.0, build specifications were integrated into the project. To offer the previous capability of batch compilation, LabVIEW now features a VI called BuildTargetBuildSpecification.vi that programmatically builds a distribution using a predefined build specification. This example shows how to use that feature to batch build applications from the command line so you can build applications from a task automation program such as Windows Task Scheduler. In LabVIEW 2011 and later, use the Build VI to programmatically build applications.
8. Software Engineering Improves Code Quality
Using proper development practices and tools benefits both small and large projects in any programming language. For LabVIEW developers, these practices are becoming increasingly important. As a LabVIEW developer, you can use a host of new tools to improve and automate many common practices such as validation and unit testing. For more information on how to incorporate these tools into your development practices, visit ni.com/largeapps.