0707.321 Principles of Software Engineering

Project C: Black Box Testing


Due Date

Both Sections: Monday, May 6

Form of Submission

Via email or printout by deadline.

Preparation

This assignment will provide you with some experience in testing software. You are encouraged to do this assignment in small groups of 2-3 (let me know who you are working with), but independent work is permitted if you worked in groups the previous two projects.

Assignment

  1. The software you will be testing is a C++ program library. Study the supplied interface specification and documentation, and develop a test plan. Your plan should consist of:

    1. Analysis of the specification
    2. A set of test cases
    3. Test data for the test cases

  2. On Friday, April 26, an implementation (mostly) satisfying the interface will be released. Libraries for both Unix (specifically "Elvis") and Windows (MS Visual C++ 6.0) will be supplied. At that time, you will be able to apply your tests against the implementation and report on your findings. Your submission should consist of the three items above plus:

    1. The results of your tests (traces)
    2. A summary of your conclusions
    3. The source code you used to conduct the tests.

    Do not attempt to hypothesize on the cause of any "bugs" you find; just describe (in as much detail as possible) any problems your tests uncover.

    Feel free to expand your test suite as necessary after April 26. The purpose of the delayed deployment is to encourage you to think about your testing strategy in the abstract first. Since black box testing is performed without consulting the implementation, not having it available right away should not be a problem.

Linking

Here are the program resources necessary for this assignment. On April 26, the "stub" version of the implementation library will be replaced with the one you will be testing.

In order to use the files in your development process, copy them to your own workarea first. They can be found on Elvis in the ~clamen/Public/SE/mailalias/ directory. Versions of the resources for Windows platforms (the library and a Visual Studio project) will be developed and placed in the student public area (specific location TBA) on Tuesday, April 22.

testaliases.cpp
Sample program (C++ program file)
mailaliases.h
Interface specification (C++ header file)
aliases.txt
Sample mailalias directory file
libmailaliases.a
Unix library (Elvis only; not portable)
Makefile
Unix makefile for linking test and library. Assumes libmailaliases.a is in your current directory

The Email Aliases Directory


class MailAliases {
public:

    static MailAliases* MakeMailAliases();
    virtual ~MailAliases() { }

    virtual bool DefineAlias(const char* alias, const char* targets) = 0;
    virtual bool UndefineAlias(const char* alias) = 0;

    virtual bool AliasDefined(const char* alias) = 0;
    virtual bool LoadAliasFile(const char* filename) = 0;

    // Caller assumes ownership of return argument (for memory management)
    virtual char* ExpandAlias(const char* alias) = 0;
    
};

Programming Interface

MailAliases instances are constructed via the factory method: MakeMailAliases(). The caller takes ownership of the directory object, and is expected to delete it when they are done with it.

The DefineAlias method takes two arguments, both character pointers (C strings). The first is the alias name, the second is a delimited list of addresses (format described below). The elements in this list can be: (1) complete email addresses, local email addresses, or the names of other aliases. Alias names consist of any string that can be formed out of the alphanumeric characters, plus: '-' (hyphen), '_' (underscore), and '.' (period). If is not legal to redefine an alias. DefineAlias returns boolean value true if successful, the boolean value false otherwise.

The UndefineAlias method takes one argument, a character pointer (C string) and returns a boolean value. If the argument names an alias defined in the directory, that alias definition is removed, and the boolean value true is returned. Otherwise, the boolean value false is returned.

The AliasDefined method takes one argument, a character pointer (C string) and returns a boolean value, based on whether or not the argument names an alias defined in the directory.

The LoadAliasFile allows one to define a set of pre-written mail aliases by reading in a text file. The file format can be described as follows: each line defines a mail alias. The alias appears on the left, followed by one or more tab characters. After the tab(s) is a delimited list of addresses, identifical in format to the second argument of DefineAlias. If any definition errors occur during the processing of the file (e.g., syntax error, circular definition), a boolean false value is returned and none of the alias definitions are added to the directory. (See Appendix B for an example of the text file format.)

To expand an alias, call the method ExpandAlias(). The method takes one argument, a character pointer (C string), the (potential) alias to expand, and returns a character pointer (C string). The caller assumes ownership of the memory referenced by that return argument, and is expected to delete the object (freeing the memory) when they are done with it.

The rules for expansion are defined as follows: the argument is looked up in the alias directory. If it names an alias, that alias is expanded (according to its definition). Then each term in that definition that might name another alias is expanded, recursively until all expansions are either complete email addresses or terms that do not name an alias (these are assumed to be local addresses). The addresses are emitted separated by commas and spaces. (See example in Appendix A below.)


Format Specification: Delimited List of Addresses

The Delimited List of Addresses consists of a sequence of atoms. Atoms are character sequences composed of all printable 7-bit ASCII characters (codes 32-127) except for the following special characters:
(   )   <   >   ,   ;   :   "   [   ]   space
The delimiters separating items in the list may be any combination of commas, spaces, or semi-colons.


Appendix A: Sample Test Program

Here is a very simple program illustrating how to use the Mail Alias facility:
#include <iostream.h>
#include "mailaliases.h"

main() {

    MailAliases* dict = MailAliases::MakeMailAliases();
    bool b = dict->LoadAliasFile("aliases.txt");

    if (! b) {
	cout << "ERROR: alias file not loaded" << endl;
    }

    char* out = 0;
    const char* in = "family";

    out = dict->ExpandAlias(in);

    int lin = strlen(in);
    cout << "IN:\t" << in << " (" << lin << ")"
	 << endl;
    
    int lout = strlen(out);
    cout << "OUT:\t" << out << " (" << lout << ")"
	 << endl << endl;

    delete out;
    delete dict;
}


When linked against a library containing a correct implementation, and run using the sample alias file below, this program would emit the following output:
IN:   family
OUT:  clamen@cs.rowan.edu, sclamen@company.ca, lclamen@notaol.com, eclamen@notaol.com, mclamen@someother.edu



Appendix B: Sample MailAlias Directory file

help            support
me              clamen@cs.rowan.edu
brother         mclamen@someother.edu
sister          eclamen@notaol.com
mother          lclamen@notaol.com
father          sclamen@company.ca
family          me; father mother, sister brother


clamen@cs.rowan.edu
Last modified: Thu Apr 25 21:09:05 2002