Testability doesn't seem very important, just one of many things on the checklist for your use cases. However, this factor is actually one of the most critical because your use cases form the basis for your system testing. Most of the other factors you must review relate as well to testability. For example, an incorrect requirement means a requirement you can't test, as does an ambiguous requirement.
A system test is a test of the system as a whole, as opposed to tests of the pieces that make it up [Muller 1996; Muller, Nygard, and Crnkovic 1997; Siegel and Muller 1996]. Object or unit tests test individual code units (classes and methods), and integration tests test subsystems that don't stand on their own as working systems. These tests should comprise the bulk of your verification efforts and can uncover most serious bugs long before they get to system test. When you deliver a working version of your system, your testing becomes a different thing.
There are several different kinds of system test [Muller, Nygard, and Crnkovic 1997]:
Validation/acceptance test: A test that validates the system against its requirements; an acceptance test is when the customer plans and executes the tests, as opposed to the developer of the system
Performance test: A test that verifies specific performance requirements and that serves as a performance benchmark for future iterations of the system
Configuration test: A test that verifies the proper operation of the system under different hardware and software environments
Installation test:A configuration test that verifies installation procedures under an array of different environments
Field test: A configuration test that tests the system in the field using real customer data
Recovery test: A test that verifies the proper recovery of system data after a disabling failure
Security test: A test that verifies the ability of the system to prevent undesirable intrusion or access to data by unauthorized users of the system
Stress test:A test that verifies the ability of the system to handle saturationlevel use (many users, many transactions, large volumes of data, and so on); the objective is to observe how the system fails, gracefully or disastrously
A test model is a system model that abstracts the characteristics of the system under test that are of interest to the tester [Siegel and Muller 1996; Muller 1998]. For example, the source code of a C++ member function is not a test model for the function; its purpose is to represent the operation of the
function in terms a programmer can understand and that a compiler can translate into machine code. A test model is a control flow or state transition model that describes the flow of control through the member function, which is what interests a tester. The actual program statements don't interest the tester, only the points at which decisions can go wrong or loops can go on endlessly.
The use cases are the test model for your validation/acceptance system test. They can include
performance and security requirements or other capability requirements, but usually the use cases do not formally model these characteristics of the system. If they do, then you must validate the system against these requirements just as with any other requirements. Otherwise, the use cases are irrelevant to the other kinds of system test. Use cases represent the objects of interest to a validation/acceptance tester: the steps that an actor goes through to use the system.
What this means in practice is that you use the narratives or the activity charts in your use cases to build your test cases. A test case is a single instance of the test model. For a use case, that means a test case is a scenario, a specific instance of the use case. If you use activity charts to model your use case, you can achieve branch coverage of the use case by having a single test case for each possible path through the flow chart. You can generate additional test cases by developing equivalence classes of data inputs to the use case.
The database affects system testing in several ways. First, the database often serves as a test bed for your system. A test bed is a configuration of data that the system uses in a test case or test suite (a collection of test cases related to one another in some way). The test bed you develop must enable you to exercise the right level of testing of your test models. In other words, your test data must permit thorough exercise of your use cases.
Note
There are several test data generation tools on the market. Let me be blunt. They don't work for me. Especially with the style of design this book presents, these tools are simply not capable of producing data that looks reasonable taking into account all the associations, inheritance generalizations, and other semantic aspects of the data. For example, if you have a table with a foreign key to a table with a foreign key to a superclass table, which in turn has a foreign key to an association class table with foreign keys to three other tables, each of which have aggregate composition associations to children tables, it's hopeless for these tools. They don't understand the connection at the semantic level, only at the structural level. Random data generation just doesn't make it for these test beds. I have failed to generate effective test beds in every single case where I've tried to use these tools on a database of any complexity.
Second, the database often contains behavior as well as data, especially for OODBMS and ORDBMS- based products, but increasingly even in RDBMS-based products. Stored procedures, triggers, methods, and operators all perform specific elements of the system use cases on the database server rather than on the application server(s) or clients. Database testing then begins to look much like any kind of system testing, not just data testing.
Third, the database may contain data you integrate from different sources. The data itself becomes part of the system under test. For example, Holmes PLC integrates multimedia documents and objects, police files, fingerprint records, and DNA sample profiles into the database. These data objects are as much a part of the system as the code that displays it. If your data is dirty, your system will fail to achieve its purpose. Data testing is thus an essential part of constructing the database-centric application system. It comprises both testing the data against the business rules (hint: don't disable integrity constraints on data loading, then forget to turn them back on) and testing data accuracy and content for correctness. Random sampling is often the best way to verify content.
In any event, getting your use cases right is critical for adequate system testing. Since system testing comes after delivery of the system, you must also keep your use cases up-to-date. If you let them diverge from your current understanding of the requirements as you iterate through design and construction, you will find it very difficult to develop effective validation test cases during system test. You must also feed back changes to the use cases into your test bed so that it accurately reflects the requirements of the system.
Summary
Your main risk at this point is that your requirements do not reflect the real needs of your stakeholders. To address this risk, you must verify requirements with a review of the use cases. Such reviews should involve both team members and external stakeholders.
You must also make sure that requirements are testable. Preparing for the system validation test that validates the finished system against its requirements means developing both test models and test beds that you can use in such tests. As always, this is an iterative process that requires revisiting the test models and test beds as your
requirements change throughout the project.
Now that you are comfortable with the whys of the system, it is time to turn to the how: database design.
Chapter 6: Building Entity-Relationship Models
The excellency of every art is its intensity, capable of making all disagreeables evaporate, from their being in close relationship with beauty and truth.
John Keats, to T. and T. Keats, January 13, 1818
Overview
Over the last 20 years, the intense art of data modeling has grown and changed with the needs of designers, though not perhaps in beauty and truth. In today's database design world, the dominant method of modeling information is the entity-relationship (ER) diagram. While I am proposing to do away with this method, or at least to expand its capabilities greatly, you cannot design databases without a familiarity with the techniques of ER diagramming. If for no other reason, you'll need to explain yourself to those who have exposure only to ER techniques. The source of many of the techniques that the UML offers originate in ER modeling. Understand ER models, and you are more than halfway to understanding object models. In particular, this chapter introduces some of the really basic modeling concepts that you use in data modeling of whatever variety.
This chapter briefly surveys ER diagramming and data modeling without going into full detail on design methods. The following chapters go into great detail on modeling techniques using UML. Usually, the comparison to ER models is easy to make; the later chapters explicitly mention any great departures from things that ER models do. This chapter introduces you to the basic data modeling concepts through ER diagrams, and the following chapters then show you how to use UML to accomplish the same things in a broader, OO context.
First, some history. Peter Chen invented the ER diagram in the early days of relational databases to model the design of those databases from a more abstract perspective [Chen 1976]. At the time, relational databases contended with network and other types of databases, particularly in academic research. Chen wanted a way to represent the semantics of the data model that would unify these database models, so he invented ER models to do exactly that.
Ten years later, ER modeling was becoming broadly used, but many competing forms emerged as the various communities that needed database design tools began to address those needs. A major leap forward came when Teorey and his coauthors proposed the extended ER model in 1986 [Teorey, Yang, and Fry 1986]. Because this paper coincided with the rise of the CASE tool as the next silver bullet, it became a standard through these tools. The extended ER model included generalization (inheritance) as a major extension to Chen's original model. The extensions came from the same work on semantic networks that informed the rise of the original OO design and programming methods.
Several other models became current in different regions of the world. Europeans focused on Natural-language Information Analysis Method (NIAM) and data modeling techniques based on it, while Americans continued to develop variations on ER diagrams. In the 1990s, the information systems industry began to adopt widely two such
variations: IDEF1X [Bruce 1992] and Information Engineering dialects, often known as "crow's-foot diagramming" [Everest 1986].
Note
These references may seem a bit long in the tooth for the fast-moving software industry. While I'd like to be able to refer you to more recent innovative training materials on these techniques, there aren't any.
About the same time, the first stirrings of the OO world began to suggest ways to use OO methods in database design. The developers of the Object Modeling Language (OML) published a paper that described how you might use OML to design databases [Blaha, Premerlani, and Rumbaugh 1988] and followed it up recently with a comprehensive book [Blaha and Premerlani 1998]. OML object modeling itself derives from ER modeling
[Rumbaugh et al. 1992, p. 271], as does the Shlaer-Mellor approach [Shlaer and Mellor 1988]. Since much of the work in OO modeling had its roots in data modeling, the fit with database design was fairly good. People began to experiment tentatively with these techniques, but because of the slow adoption rate of OO, the techniques did not become popular. As OO adoption speeds up, that is changing quickly, as evidenced by the techniques in this book. So what exactly is entity-relationship diagramming, and what can it do for you?