COPYRIGHT NOTICE. COPYRIGHT 2008-2011 by Clinton Jeffery. For use only by the University of Idaho CS 384 class.

Lecture Notes for CS 384 Software Engineering II

Go Over the Syllabus

It would probably be good to start 1/class period scrumming sooner rather than later in the semester...like at or near the beginning of the semester. Scrum = 10 minutes per class, see examples later down in lecture notes.

What CS 384 is all about

CS 384 is all about the back-end software engineering issues: programming, debugging, testing, managing change, and so on. The goal for CS 384 is to learn back-end software engineering by completing the project designed in CS 383.

Announcements

Taking Stock of our Situation

From last semester we have requirements and design documents, and prototype work, that have a lot of useful ideas and a lot of flaws. We have to proceed and do our best and learn what we can along the way.

Team Assignments

Does anyone think (or stronger: request) that the teams need rearranging?

No Class Monday

Monday is Martin Luther King Jr. day.

Top Comments from the 383 Folders

"too" was incorrectly overused
it only means "also" or "as well"
use case task granularity can be tricky
UML diagram editing involves a lot of tasks. You are probably be missing some. You need them to even get a handle on what classes you will need.
class diagrams are really all about the associations
you probably haven't worked out associations' details enough
class diagrams are insufficient to express an OO class design
you need detailed descriptions of the classes and associations
classes are categorized as: entity, boundary, and control
if you categorize yours, you may discover missing design elements
states in statecharts are nouns
a statechart depicts the different values of some member variables! and under what circumstances those get assigned new values.
when do you need a: collaboration or activity diagram?
when your details for how to work out a step in a use case involve several objects, or when their communication patterns are non-trivial
when do you not need a sequence or similar diagram?
when the logic described is trivial

Dr. J's Wonderful New Requirements

If your project wasn't already doing
Your project must target both Linux and Windows (and Mac if possible).
Really, this stems from the fact that your project should "cover" the typical users, who are future UI CS 383 students. One team member should be assigned to ensure each port is continually tested. Like each week.
Your project must target "projects", not just diagrams
Really, a software engineering project does not create one diagram, it creates a set of interconnected diagrams.
Your project must support Use Case, Class, Statechart, and Collaboration diagrams.
Of the 15 UML diagram types, few projects use them all. But in CS 383, these four provide minimal coverage. Arguably, activity and sequence diagrams might also deserve support.
Your project must resist user/author semantic bugs in UML diagrams.
Why would we write software that made it easy to draw broken diagrams? CS 383 students are learning UML and need all the help they can get. If you think of it as being like a compiler or syntax checker, it might have a number of warning and error messages it would spit out. But if you think of it as a "syntax-directed editor", you might want every successful use case to end with a legal UML document, where the tool prevents illegal nonsense from being drawn.

The Errors your UML Diagram Drawing Tool Must Prevent Include

Prevent or at least detect/warn against the following common CS 383 newbie UML errors
Unnamed classes, associations, states, transitions etc.
Students like to draw blank lines connecting boxes.
Undescribed classes, associations, states, transitions etc.
Students like to draw the diagrams but never define what is in them. Use case descriptions have a precise format; classes, associations, states, events, etc. at least need a prose text paragraph description. Printing out the diagram should usually involve printing out the picture followed by a legend/dictionary/detail description of the diagram's contents.
Untraceable connections between diagrams
There are frequently typos between different parts of a software design, where a given class/association/state is spelled differently in different spots. We basically want to ensure that every class referenced in a use case description or statechart exists in the class diagram, and want similar consistency checks for methods (verbs in use cases, events in statecharts, message sends in collaboration diagrams, etc.).

LaTeX help?

Check out
TeX Studio, an "IDE" for TeX/LaTeX. Doesn't make it WYSIWIG, but provides various forms of IDE help. You may want to experiment with LaTeX WYSIWYG tools (there are some good ones) but any tool must make changes that are minimal/human-readable or they defeat the point of using LaTeX.

Project File Organization

Let's talk file organization.

Team that requested to stay on Mercurial on google code: specific instructions for me to check out your project, please.

Teams already have a top-level project directory (phunctional/ and pummel/). They should contain src/ doc/ and web/ directories.

What's in our repository?

So some of these suggestions may not apply to your team, but please consider whether any do.

Mapping Models to Code

If we did things right last semester, we should be full-speed on coding, starting ASAP.

Goals:

  1. implement all the use cases
  2. implement working subsystems based on the design
  3. refine, and flesh out aspects of requirements/design where necessary
  4. integrate subsystems to form a coherent whole
Working on an object design model, and turning one to code, involves many transformations that are error prone.

Potential problems. You may need to...

  1. modify things to speed them up or make things more modular
  2. implement "associations" in varying ways, since languages do not have associations, only models do
  3. who enforces required "contract" properties such as making sure that parameter values are within valid range?
  4. new requirements show up during coding or later
  5. requirements not quite right, need to "adjust" on the fly
  6. design not quite right
  7. when we go to code, we discover some of these things
  8. add undocumented parameters that we need
  9. add extra class member variables
  10. pile up enough surprise changes...and the design doc gets worthless
Chapter 10 suggests some approaches to implementing your model that might help a bit with all this. Its examples are Java-based. Adapt as needed.

Four Types of Transformations

model transformations
editing the class diagram. Simplify or optimize a class diagram, correct it, or fill in missing parts. The more code already written, the more code may have to be changed or recoded to stay consistent.
refactoring
an improvement to the code. sometimes this doesn't change the model. If the model needs to be changed, you hope to minimize such change, but failing to update the model leaves other developers unaware. Refactor in TINY incremental steps, and test each step, or risk pandemonium. Note on refactoring example in Figures 10-2, 10-3: some refactorings like "set parent class to new superclass" are pretty limited in languages with no multiple inheritance... Work through those examples pp 396-397 and ask Dr. J about any parts you find unclear.
forward engineering
generate the code from the model. often mechanical, or easy. This is what we need to do right now. Review how to do this for classes, inheritance, public vars (vs. private w/ getters and setters?), aggregation, user defined associations...
reverse engineering
construct an object model from the code. This is often the first step in a fix-the-legacy-program job. Note: some aspects of code are hard to map back onto model!

Feedback on HW1

Phunctional

Pummel

Guidelines for successful transformations

address a single criteria at a time.
if you are improving speed, don't go refactoring your classes at the same time.
keep your transformations local.
change as few methods or as few classes as possible. If you change the parameters of a function, keep both old and new around for testing (at least for awhile). If you are changing lots of subsystems at once, this is an architecture change, not a model transformation.
validate each transformation
maybe it looks easy and obvious, but maybe you missed something

Mapping associations to collections

Unidirectional one-to-one associations are the best special case, you can implement them as a pointer.

Bidirectional one-to-one associations introduce a mutual dependency, you can almost just use two pointers, but be careful of the methods to establish and break such associations, to keep things consistent. Things get interesting when multiplicity >1 is involved.

one-to-many

The many-folks may have a single reference back to the one, but the one will need what--an array (often dynamically sized) of references. For low multiplicities, this is almost what linked lists were born for, but for higher multiplicities a linked list is too slow. The example in Figure 10-10 in the text uses a Set (really, a HashSet). Whatever language you are using, you will need to study the container classes, and if you are using a strongly typed language, understand how the container classes handle their generic, polymorphic nature. For example, in C++ the way container classes manage to work with any type is using templates. In C, one would just break the type system and typecast pointers as needed. How do Java's container classes (such as HashSet) handle this problem? If we don't know, we better find out ASAP, and you-all should know it well before the midterm!

A key point are the methods that establish (and break) the objects' participation in a given association. In Figure 10-10 examine and understand the dovetailing between the removeAccount in class Advertiser and the setOwner in class Account.

many-to-many

Both sides have a collection, and sets of operations on both sides must keep these collections consistent. See Figure 10-11. Many supreme software engineering gurus just throw up their hands and demand that a new class be introduced in order to implement the association. Don't be surprised if a lot of things in the UML model get turned into classes in the implementation, and don't expect implementation classes to all have a mapping back to a model class.

Qualifiers

Earlier I have said "many" multiplicities can be reduced by using qualifiers, which amount to introducing a hash table or similar structure to look up references. The Java class for doing this might well be called Map. Figure 10-12 is very interesting, but its UML seems bogus.

Optimizing the Object Design Model

Direct translation of model to code is often inefficient. Inefficiency is often due to redundant memory references. You may need to optimize access paths between classes.
repeated association traversal
x.y.z.a, if it is done often enough, may warrant x having a direct reference to z (or even, depending on its type, to a).
replace "many" associations with qualified associations
add hash tables or other means of quickly picking subjects from "many" associations, if multiplicity is large enough, like >> 10
misplaced attributes
if a class has no interesting behavior, or is only referenced from a single calling/owning class (for example some aggregations are like this), it is a candidate for absorption into the parent class. See the Person and SocialSecurity example
lazy construction
if construction is slow and the object is not used in every single execution, consider a proxy for it that constructs it only if it is used.
cache expensive computations
for example, if method m() is called a lot and is slow, AND if m() is a pure math function or you can otherwise prove it is safe to do so, remember the results of previous calls to m() to reduce future calls. (Dynamic programming).

Sprint Meetings

A sprint meeting consists of three parts:
Review (16 minutes)
Except on the first one, review the outcome of the past sprint. <= 8 minutes per team, in front of class. Demo finished deliverables. Graded on technical content and communication/relevance/value.
Reflection (4 minutes)
Answer two questions: What went well? What could be improved? Process improvement is all extra credit.
Planning (20 minutes)
12 minutes in your team, updating requirements and backlog. 4 minutes per team to negotiate with your instructor on items committed to complete for the next sprint.
The instructor will often provide one or more Required elements for the following week's sprints, to go along with whatever team-specific goals you formulate.

HW#2

lecture5

Borg Scholars

Dr. Anita Borg (1949–2003)

Anita Borg believed that technology affects all aspects of our economic, political, social and personal lives. A technology rebel with a cause, in her life she fought tirelessly to ensure that technology’s impact would be a positive one. It was this vision that inspired Anita in 1997 to found the Institute for Women and Technology. Today this organization continues on her legacy and bears her name, The Anita Borg Institute for Women and Technology (www.anitaborg.org).

Dr. Anita Borg devoted her adult life to revolutionizing the way we think about technology and dismantling barriers that keep women and minorities from entering computing and technology fields. Her combination of technical expertise and fearless vision continues to inspire and motivate countless women to become active participants and leaders in creating technology.

In her honor, Google is proud to honor Anita's memory and support women in technology with the 2012 Google Anita Borg Memorial Scholarship. Google hopes to encourage women to excel in computing and technology and become active role models and leaders in the field.

Google Anita Borg Scholarship recipients will each receive a $10,000 award for the 2012-2013 academic year. A group of female undergraduate and graduate students will be chosen from the applicant pool, and scholarships will be awarded based on the strength of each candidate's academic background and demonstrated leadership. All scholarship recipients and finalists will be invited to attend the Annual Google Scholars' Retreat in Mountain View, California in 2012.

You can hear from some of this year's Anita Borg Scholars on how receiving the scholarship has impacted them: The Annual Google Scholars' Retreat at the Googleplex

We know how important a supportive peer network can be for a student's success. All Google scholarship recipients and finalists will be invited to visit Google headquarters in Mountain View, California for the 2012 Google Scholars' Retreat. The retreat will include workshops, speakers, panelists, breakout sessions and social activities scheduled over a 3-day period. Students will have the opportunity to explore the Googleplex and enjoy the San Francisco Bay Area as they get to know other talented computer science students from across the country.

The Retreat Who can apply?

Applicants must satisfy all of the following criteria to be eligible:

Citizens, permanent residents, and international students are eligible to apply. Past applicants and finalists are also encouraged to re-apply. If you have any questions, please email anitaborgscholarship@google.com.

The Google Anita Borg Memorial Scholarship is a global program. If you are a student who will not be enrolled at a university in the United States for the 2012-2013 academic year, please visit the Google Scholarships Homepage to learn more about our scholarship opportunities for students around the world. Application process

Please complete the online application. If you are a first time user, you will need to register; if you are already registered, simply login!

You will also be asked to submit electronic versions of your resume, essay responses, transcripts, and name and email of your referrers. Please scan your transcripts and enrollment confirmation into electronic format (PDF format preferred for all requested documents).

Deadline to apply: Monday, February 6, 2012.

Questions? Visit the Frequently Asked Questions page (FAQ) or email us at anitaborgscholarship@google.com.

Pair Programming

Thoughts from Wray's "How Pair Programming Really Works"

Note also the ideas from 21 ways to hate pair programming.

Software Project Management

Surprisingly, both the CS 384 schedule I inherited originally from my UI forbears and the Bruegge text covers this project management stuff at the end. I am moving it up. Perhaps this subject should have been a CS 383 topic, and will get moved there in future years. Anyhow, read Chapter 14.

Perhaps instead of moving it ALL to 383, we should view this section as adding depth to whatever we have said and done about this topic so far. Managing a software project includes:

Project planning
requirements (which we did study), estimation and scheduling (which we did not study much)
Project monitoring and control
how to keep the team and management up to date? how to stay on the same page in the face of changes? Note that I (management) do not feel the mechanisms we used last semester kept me up to date.
Risk Management
measuring or assessing risk; developing strategies deal with risk. Strategies include: get someone else to take the risk, concluding the project is not worth the risk, reducing the negative effect of the risk, or being prepared to deal with what you see may come.
Software Process
We've under-discussed this aspect of SE. It is really all about what procedures or structure are imposed on the humans doing the software, in order for management to be able to have a chance of tracking the project and knowing what's going on .
Dealing with Problems
Project managers, developers, and customers may introduce problems which affect the whole project in different ways. If developers ... that can kill a project. If customers the project can fail.

Project Management in 383/384

In this class we have already seen many issues related to project management. Some of these are inherent in the artificial university environment we are in, some are due to instructor or student character traits.

Experiences with Project Management

Sprint Reflection

Pummel
Went well: work ethic
Needs improvement: establish regular meeting time, more frequent communications/status updates between meetings
Goals this week:
Phunctional
Went well: drawing functions, working toolbar GUI
Needs improvment: directory/file reorganization, integrating image files into (Requirements + Design) documents
Goals this week:

Sprint Planning Meeting

Use the remaining time today to plan the next sprint.

Example: how to deal with Dr. J's "project=set of interconnected diagrams" requirement.
Option A: folder-based
Like Java, treat a (sub)directory as a unit of project-ness. Treat project membership implicitly by means of directory access.
Option B: project-file
Store the set of files associated with a given project in a file. Some IDE's define their own (possibly XML-based) file format. One could alternatively use some designated representation within a .tex file or a "master diagram file" to store the information about other, related diagrams. For example, a UML master class diagram might have a special comment that listed other diagrams (subset, detail-oriented class diagrams and other UML diagram types for the project).
Lecture 6

Reminder

Include HW#2 in your team's plans this week. I have amended it to include: develop a more complete backlog of all the major tasks you need. Expect to refine that continuously as the project proceeds.

Project Scheduling

Bruegge et al don't say a whole lot about project scheduling. In addition to what he does have to say in chapter 14, your assigned reading shall be this fine document which apparently originated in the IT office of the great state of California. Among other things, it includes example Gantt and PERT charts. You should read up on them.

A Gantt chart is a list of activities in mostly-chronological order, side-by-side with an array of corresponding bar-graph timelines. It is good for smaller projects.

A PERT (Project Evaluation Review Technique) chart is believed to scale better to larger projects; it gives up the linear list-of-activities format in favor of an arbitrary task dependency graph. Each node in the graph is annotated with schedule information. California's example uses the format on the left; Visio provides the more detailed one on the right. PERT charts can be processed computationally (like a spreadsheet), and by applying the durations and dependencies to a particular calendar timeline, the chart can be used to calculate the starts, ends, amount of slack, and critical path through the chart.
Task Name
task # input
start date end date
versus
early start duration early end
Task Name
late start    slack      late end  

Dr. J's take on the scheduling thing (have to try this some time):

A couple small Design-related Asides

Mapping Contracts to Exceptions?

A good object-oriented design may have "contracts" for method behavior, most commonly a method may be said to require 0 or more preconditions, and to guarantee 0 or more postconditions or invariants. In Java, you may implement contracts by inserting runtime checks, which slow execution down, and if the contract is violated a class can report it by generating an exception. The better way to implement this is to allow such checks to be easily turned on/off at compile time. And if you use exceptions, be sure you handle them; one of the most irritating and common failures in Java applications, which users really hate, are ExceptionNotHandled errors. Aggressive use of throw/try/catch can increase your total code size by 100%, but aggressive error handling is usually better than no error handling, and you have the same problems in most languages.

Object Persistence

Basic idea: when objects (and UML relationships) have to survive across runs, what do you do? Serialization is the act of taking some structure and converting it to a string, from which the structure can be restored. It works for both persistence and mobility of that structure across machines. Java tends to support Serialization a lot.
serialize whole universe
simplest notion of persistence, used in early programming languages, not very efficient/scalable
serialize disjoint structures independently
single database table might store mixed types of data. Need a primary key to get the data back, still not super scalable.
one table per class
each table needs a primary key, may need lots of references across tables (foreign keys). Keep it Simple, or go take the database course.

Supporting Resources

Untested code is incorrect code. All code is guilty until tested innocent.
- various internet pundits

Test-Driven Development Begins with Automated Test Tools

Please learn how to do unit testing this week if you do not already know how, and turn in a doc/384-hw2.html that reports on your progress.

Introduction to Software Testing

Reading Assignment: Read Bruegge Chapter 11.

Testing is the process of looking for errors (not the process of demonstrating the program is correct). Bruegge gets more subtle, calling testing a matter of looking for differences between the design (expected behavior) and the implementation (observed behavior). Passing a set of tests does not guarantee the program is correct, but failing a set of tests does guarantee the program has bugs.

Testing is best done by someone other than the person who wrote the code. This is because the person who wrote the code would write tests that reflect the assumptions and perspectives they have already made, and cannot be objective.

Kinds of errors include:

Syntax & semantics errors
typos, language misuse
Logic errors
I/O errors
formatting & parsing failures, network handshake trouble, ...
Design errors
misinheritance
Documentation errors
program does one (reasonable) thing, document says another

Buzzwords

software reliability
probability P that a software system will not fail within time T under specified conditions (hardware OK, power steady, etc.)
failure
any deviation from expected behavior; when an erroneous state results in a discrepancy between the specification and the actual behavior
fault
synonym for defect, or bug
fault avoidance
looking for bugs via static analysis, such as examining source code or running a static bug checker (e.g. lint) or model checker (e.g. ESC/Java)
fault detection
experiments during development to identify erroneous states and their causes
fault tolerance
mechanisms for handling or recovering from faults at runtime.
erroneous state
manifestation of a fault at runtime
test driver
For component testing, a fake "main()" that simulates the context in which a component will be run, and calls the test component. The driver determines what gets tested in the component.
test stub
For component testing, a simulation of the child components that are called by the component under test. Fake versions of associated classes that this component interacts with. Fake results of queries or computations (return values) that this component can use for its test. All this fakeness means that testing on "live" data after integration is often a whole new ballgame.

Bolden of the Day

Bruce found this interesting blog on why Testing Trumps Design

Lecture 7

Repository Update

I saw extensive action (in SVN?) by team Pummel, which provided these SSRS and SSDD. Is team Phunctional committing stuff that I am not getting, for example, am I looking in the wrong place?

Notes from current version of Pummel's docs

Different Kinds of Testing

Bruegge Figure 11-1 is a cool summary of testing activities, with roles (for certain tests) for not just the Developer, but also the Client Customer and the User.

Kinds of testing include:

black box
tests written from specifications, cast in terms of inputs and their expected outputs
white box
tests written with the program source code in hand, for example, to guarantee that every line of code has been executed in one or more tests.
component inspection
hey, reading the code looking for bugs is a form of testing, and it can be very productive
unit testing
testing individual functions, classes, or modules
integration testing
testing how units interact; culminates in a structural test
system testing
functionality, performance, acceptance test, installation test
regression testing
re-testing, preferably automatically, all your past tests, because fixing new bugs often reintroduces old ones.

Test Cases and Test Plans

Bruegge 11.5.2 gives a terse and inadequate overview of test plans and test cases. Lecture notes material is adapted from Lethbridge and Laganiere, and other sources.

Test Cases

A test case is a set of instructions for exercising a piece of software in order to detect a particular class of defects, by causing them to occur. It includes a set of input data and expected output. A test case often involves running many tests aimed at that particular defect to be detected. A test case has five components, given below. The purpose for this much detail is presumably to support reproducing and reviewing the test results by a third party (for example, the boss, or more likely the developer who must debug things) after the tester is finished.

name
location
the full path name of the program
input
input data or commands. May be files, redirected keyboard input, or a recorded session of GUI input, net traffic, database results, etc.
oracle
expected test results against which the execution may be compared. If the expected output includes outgoing network traffic, graphical display of certain pixel patterns, etc, it will be difficult to automate the comparison, a comprehensive recording facility or a smart human can do the job.
log
actual output from the test.
restoration (optional)
instructions on how to restore the system to its original state after test (if needed)
priority
different tests have different priority which affects the order and frequency with which they should be run.

Test Plans

A test plan is a bigger document than a test case that that describes how a system is to be tested, including the set of test cases that are used. A test plan should be written before testing starts. Lethbridge points out that it can be developed right after requirements are identified. In recent years the "extreme programming" community has argued in favor of writing the test cases first, before coding. If you can't come up with satisfactory test cases, you certainly don't know the problem yet well enough to code a solution or know whether your program is in fact a solution.

In-class exercise: if we wanted test cases for our semester project, what should be in them?

The Test Documents

Test Plan

Scope, approach, resources, schedule. This is by definition given in the ANSI/IEEE Standard for Software Test Documentation.

Is your test plan a product, or a tool? If you are using your test plan to sell your software, e.g. to a company that will use it in-house, they may want an impressive test plan to give them some confidence in your code. If you are making a product that requires a government or standards-organization approval, you may have to meet their standards. Otherwise...

A test plan is a valuable tool to the extent that it helps you manage your testing project and find bugs. Beyond that it is a diversion of resources.
- from [Kaner et al]
as a practical tool, instead of a product, your test documentation should:

Test Case Specifications

These are documents, discussed in an earlier lecture, that list inputs, drivers, stubs, expected outputs, etc.

Test Incident Reports

These reports give actual results from a test run; often they are given as differences from expected output. These are similar to bug reports, and in fact, bug reports can often be turned into test cases + test incident reports.

Test Report Summary

List the results of testing. Prioritize failures in order to marshall developer attention and resources where they are most needed. Draw some conclusions about the current state of the software.

Test Plan

The following outline is from:

TEST PLAN OUTLINE (IEEE 829 Format)

  1. Test Plan Identifier
  2. References
  3. Introduction
  4. Test Items
  5. Software Risk Issues
  6. Features to be Tested
  7. Features not to be Tested
  8. Approach
  9. Item Pass/Fail Criteria
  10. Suspension Criteria and Resumption Requirements
  11. Test Deliverables
  12. Remaining Test Tasks
  13. Environmental Needs
  14. Staffing and Training Needs
  15. Responsibilities
  16. Schedule
  17. Planning Risks and Contingencies
  18. Approvals
  19. Glossary

IEEE TEST PLAN TEMPLATE

TP.1.0 Test Plan Identifier

Some type of unique company generated number to identify this test plan, its level and the level of software that it is related to. Preferably the test plan level will be the same as the related software level. The number may also identify whether the test plan is a Master plan, a Level plan, an integration plan or whichever plan level it represents. This is to assist in coordinating software and testware versions within configuration management.

Keep in mind that test plans are like other software documentation, they are dynamic in nature and must be kept up to date. Therefore, they will have revision numbers. You may want to include author and contact information including the revision history information as part of either the identifier section of as part of the introduction.

TP.2.0 References

List all documents that support this test plan. Refer to the actual version/release number of the document as stored in the configuration management system. Do not duplicate the text from other documents as this will reduce the viability of this document and increase the maintenance effort. Documents that can be referenced include:

TP.3.0 Introduction

State the purpose of the Plan, possibly identifying the level of the plan (master etc.). This is essentially the executive summary part of the plan.

You may want to include any references to other plans, documents or items that contain information relevant to this project/process. If preferable, you can create a references section to contain all reference documents.

Identify the Scope of the plan in relation to the Software Project plan that it relates to. Other items may include, resource and budget constraints, scope of the testing effort, how testing relates to other evaluation activities (Analysis & Reviews), and possible the process to be used for change control and communication and coordination of key activities.

As this is the "Executive Summary" keep information brief and to the point.

lecture#8 began here

Sprint Monday == Sprint Meeting

When in doubt about What to Do

Ask what each person (or miniteam of 2-3 folks) is going to get done this week-- and look back at backlog and plan (Gantt or PERT) for what needs to be done first!

Current State of Projects

TP.4.0 Test Items (Functions)

These are things you intend to test within the scope of this test plan. Essentially, something you will test, a list of what is to be tested. This can be developed from the software application inventories as well as other sources of documentation and information.

This can be controlled and defined by your local Configuration Management (CM) process if you have one. This information includes version numbers, configuration requirements where needed, (especially if multiple versions of the product are supported). It may also include key delivery schedule issues for critical elements.

Remember, what you are testing is what you intend to deliver to the Client.

This section can be oriented to the level of the test plan. For higher levels it may be by application or functional area, for lower levels it may be by program, unit, module or build.

Software Risk Issues

Identify what software is to be tested and what the critical areas are, such as:
  1. Delivery of a third party product.
  2. New version of interfacing software
  3. Ability to use and understand a new package/tool, etc.
  4. Extremely complex functions
  5. Modifications to components with a past history of failure
  6. Poorly documented modules or change requests
There are some inherent software risks such as complexity; these need to be identified.
  1. Safety
  2. Multiple interfaces
  3. Impacts on Client
  4. Government regulations and rules
Another key area of risk is a misunderstanding of the original requirements. This can occur at the management, user and developer levels. Be aware of vague or unclear requirements and requirements that cannot be tested.

The past history of defects (bugs) discovered during Unit testing will help identify potential areas within the software that are risky. If the unit testing discovered a large number of defects or a tendency towards defects in a particular area of the software, this is an indication of potential future problems. It is the nature of defects to cluster and clump together. If it was defect ridden earlier, it will most likely continue to be defect prone.

One good approach to define where the risks are is to have several brainstorming sessions.

  • Start with ideas, such as, what worries me about this project/application.

    Features to be Tested

    This is a listing of what is to be tested from the USERS viewpoint of what the system does. This is not a technical description of the software, but a USERS view of the functions.

    Set the level of risk for each feature. Use a simple rating scale such as (H, M, L): High, Medium and Low. These types of levels are understandable to a User. You should be prepared to discuss why a particular level was chosen.

    It should be noted that Section 4 and Section 6 are very similar. The only true difference is the point of view. Section 4 is a technical type description including version numbers and other technical information and Section 6 is from the User.s viewpoint. Users do not understand technical software terminology; they understand functions and processes as they relate to their jobs.

    Features not to be Tested

    This is a listing of what is NOT to be tested from both the Users viewpoint of what the system does and a configuration management/version control view. This is not a technical description of the software, but a USERS view of the functions.

    Identify WHY the feature is not to be tested, there can be any number of reasons.

    Sections 6 and 7 are directly related to Sections 5 and 17. What will and will not be tested are directly affected by the levels of acceptable risk within the project, and what does not get tested affects the level of risk of the project.

    Approach (Strategy)

    This is your overall test strategy for this test plan; it should be appropriate to the level of the plan (master, acceptance, etc.) and should be in agreement with all higher and lower levels of plans. Overall rules and processes should be identified. If this is a master test plan the overall project testing approach and coverage requirements must also be identified.

    Specify if there are special requirements for the testing.

    Other information that may be useful in setting the approach are: How will meetings and other organizational processes be handled?

    Item Pass/Fail Criteria

    What are the Completion criteria for this plan? This is a critical aspect of any test plan and should be appropriate to the level of the plan. This could be an individual test case level criterion or a unit level plan or it can be general functional requirements for higher level plans. What is the number and severity of defects located?

    Suspension Criteria and Resumption Requirements

    Know when to pause in a series of tests.

    If the number or type of defects reaches a point where the follow on testing has no value, it makes no sense to continue the test; you are just wasting resources.

    Specify what constitutes stoppage for a test or series of tests and what is the acceptable level of defects that will allow the testing to proceed past the defects.

    Testing after a truly fatal error will generate conditions that may be identified as defects but are in fact ghost errors caused by the earlier defects that were ignored.

    Test Deliverables

    What is to be delivered as part of this plan? One thing that is not a test deliverable is the software itself that is listed under test items and is delivered by development.

    Remaining Test Tasks

    If this is a multi-phase process or if the application is to be released in increments there may be parts of the application that this plan does not address. These areas need to be identified to avoid any confusion should defects be reported back on those future functions. This will also allow the users and testers to avoid incomplete functions and prevent waste of resources chasing non-defects.

    If the project is being developed as a multi-party process, this plan may only cover a portion of the total functions/features. This status needs to be identified so that those other areas have plans developed for them and to avoid wasting resources tracking defects that do not relate to this plan.

    When a third party is developing the software, this section may contain descriptions of those test tasks belonging to both the internal groups and the external groups.

    Environmental Needs

    Are there any special requirements for this test plan, such as:

    Staffing and Training needs

    Training on the application/system.

    Training for any test tools to be used.

    Section 4 and Section 15 also affect this section. What is to be tested and who is responsible for the testing and training.

    Responsibilities

    Who is in charge?

    This issue includes all areas of the plan. Here are some examples:

    Schedule

    Should be based on realistic and validated estimates. If the estimates for the development of the application are inaccurate, the entire project plan will slip and the testing is part of the overall project plan. At this point, all relevant milestones should be identified with their relationship to the development process identified. This will also help in identifying and tracking potential slippage in the schedule caused by the test process.

    It is always best to tie all test dates directly to their related development activity dates. This prevents the test team from being perceived as the cause of a delay. For example, if system testing is to begin after delivery of the final build, then system testing begins the day after delivery. If the delivery is late, system testing starts from the day of delivery, not on a specific date. This is called dependent or relative dating.

    Planning Risks and Contingencies

    What are the overall risks to the project with an emphasis on the testing process? Specify what will be done for various events, for example:
    Requirements definition will be complete by January 1, 19XX, and, if the requirements change after that date, the following actions will be taken:
    Management is usually reluctant to accept scenarios such as the one above even though they have seen it happen in the past.

    The important thing to remember is that, if you do nothing at all, the usual result is that testing is cut back or omitted completely, neither of which should be an acceptable option.

    Approvals

    Who can approve the process as complete and allow the project to proceed to the next level (depending on the level of the plan)?

    At the master test plan level, this may be all involved parties.

    When determining the approval process, keep in mind who the audience is:

    Glossary

    Used to define terms and acronyms used in the document, and testing in general, to eliminate confusion and promote consistent communications.

    Test Case Examples

    Many of the test case examples you will find on the web are provided by vendors who want to sell their software test-related products. There are whole (expensive) products specifically for Test Case Management out there. Such commercially-motivated examples might or might not be exemplary of best practices. You can evaluate them to some extent by asking: How well does this example fulfill the criterion given by Dr. J above?

    Examples

    (missing/broken) manual test case instructions
    test case report from Vietnam
    manual test case
    alleged Microsoft-derived test case format
    foo OpenOffice Test Case Template Example (thanks Cindy and Leah)

    Historical (Past Class, java team) Test Example

    What To Do?

    What do we want to do for our class? We want test cases that are readable, repeatable, and relevant. These criterion include printable in report form, traceable back to specific requirements, and readily evaluable as to whether they turned up a problem or sadly, failed to do so.

    Are there any obvious tools we should be using? If you have a choice between manually documenting your test cases and adopting a tool for it, what are your tool options and which would you prefer?

    Among the most interesting open source candidates there are

    Unit test tools?
    Do our Unit test tools include test case management? Are they generalizable to all types of tests, not just unit tests?
    STAF
    Software Test Automation Framework
    TestLink
    Test Manager plugin for Trac
    If you use Trac, this might be good
    What other tools do you know, or can you find?

    Corny Real-Life Example of an Automated Test Case

    In the Icon programming language (a pair of large C programs), a suite of test cases was developed by creating tests each time a new feature was added to the language. The suite was augmented with new test cases when pernicious bugs were reported by real users. One test case, for the "synchronous threads" feature in the language, looks like this
    Namecoexpr
    Location.../unicon/tests/general/coexpr (from coexpr.icn)
    Input.../unicon/tests/general/coexpr.dat
    Oracle.../unicon/tests/general/coexpr.std
    Log.../unicon/tests/general/coexpr.out (generated each run)
    In this case, "diff coexpr.std coexpr.out" shows whether the test case matches the expected case. One part of Bruegge's test case definition that is missing are instructions on how to run the program in order for it to produce the log, for example in this case there is a shell script that you run in order to run the test case with the proper input and output redirection (for example, to catch error output in the log)

    Example of (white box) testing: Testing Loops

    If your job is to write tests for some procedure that has a loop in it, you can write tests that:
    1. skip the loop entirely
    2. execute only one iteration of the loop
    3. execute two iterations
    4. execute M iterations, for some random 2 < M < N-1
    5. execute (N-1), N, and (N+1) iterations
    where N is the maximum number of allowable passes.

    Peek Back at Example Test Cases

    Including the OpenOffice one Cindy recommended.

    Objectives to Insert into your Sprint Planning

    Unit Testing

    One method of unit testing that is statistically shown to be cost-effective is to read the source code! This may be done with the aid of a partner or team, performing either a walkthrough (where the code author sets the agenda and others review) or an inspection (where the leadership sets the agenda).

    Whole books have been written about methods of writing good tests, much of which boils down to: write tests to challenge the boundary conditions and assumptions that programmers typically make when writing code.

    Unit Testing Documentation

    Testing is like detective work?

    A SE author named Lethbridge makes an unfortunate analogy between programmers and criminals; they have a modus operandi, and once you find what type of bugs a programmer is writing in one place, the programmer may well repeat similar bugs elsewhere in the code.

    In selecting test cases, look for equivalence classes

    You usually cannot test all the possible inputs to a program or parameters to a procedure that you wish to test. If you can identify what ranges of values ought to evoke different kinds of responses, it will help you minimize test cases to: one representative from each class of expected answer, plus extra tests at the boundaries of the equivalence classes to make sure the ranges are nonoverlapping.

    (back to) Unit Testing (Bruegge 11.4.3)

    Motivation: Most important kinds of unit tests:

    equivalence tests

    partition possible range of inputs into equivalence classes. develop at least 2 test cases for each class: a valid input, and an invalid input. Example:
    int getNumDaysInMonth(int month, int year) { ... }
    
    Equivalence classes: months with 31 days, months with 30 days, and February, which has leap years. Three equivalence classes means at least 6 tests.

    boundary tests

    Focus on boundaries between equivalence classes. Developers and routine tests often overlook boundaries (0, null input, y2k, etc.). Note: watch out for combinations of invalid input. Two parameters x and y might both have interesting values that separately would be legal, but taken together denote an event that the code can't handle.

    path tests

    Comments on Current Hg

    Pummel Phunctional

    Some C++ Unit Testing Frameworks

    Question: how does one evaluate unit testing frameworks?

    Some (Lethbridge) Bug Categories

    Purpose of this list: construction of (mostly white box, mostly unit-) test cases. A thorough white box tester might perform and document having performed the following examination of the code to be tested.
    For each unit to be tested
         For each category given below
             Can this kind of bug occur in your unit?
    For each place where it can, write one or more test cases that looks for it.
    Incorrect logic
    < instead of >; missing an = somewhere, etc.
    Performing a calculation in the wrong place
    such as: work done before or after a loop that needed to be in a loop in order for it to be correct.
    Not terminating a loop or a recursion
    except in special circumstances, every loop can be checked to make sure it makes forward progress towards a termination condition
    Not establishing preconditions; not checking your inputs
    examples: an integer is passed that is out of range; a string is passed that is too long or not well-formed.
    Not handling null conditions
    often a by-product of a failure of an earlier routine
    Not handling singleton/nonsingleton conditions
    if "there can be only one", how do you ensure it?
    Off by one errors
    common in array indexing, novice code, translated code
    Precedence errors
    beyond "times is higher than plus", it is unwise to leave off parentheses
    Use of bad algorithms
    how do you test for badness? There is bad="too slow". There is bad="doesn't always succeed", "bad=answer sometimes wrong", and variants.
    Not using enough bits/not enough precision
    when, for example, are 32-bit integers not enough? this would seem to be statically checkable.
    Accumulating a large numerical error
    a specialty province, for some codes it is an urgent topic and the subject of extensive testing
    Testing for floating point equality
    Duh. If they are calculated, float f1 is almost never == float f2. Don't check if x == 0.0, check if abs(x) < 0.000001 or whatever.
    Deadlock/livelock
    Classic bugs for threaded programs. Special case of "incorrect logic".
    Insufficient response time (on minimal configurations)
    Do you test on the slowest machine that you must run on? If not, can you write artificial tests to simulate that level of performance?
    Incompatibilities with specific hardware/software configurations
    Do you test on every HW/SW configuration you must run on? To what extent can you automate this?
    Resource leaks
    Do you close and free every OS or window system resource you use?
    Failure to recover from crashes
    Do you test the whole "crash" experience and ensure that things come back up gracefully?

    Coverage Testing

    Coverage means: writing tests that execute all the code. Since a significant portion of errors are due to simple typos and logic mistakes, if we execute every line of code we are likely to catch all such "easy" errors.

    There are at least two useful kinds of coverage: statement coverage (executing every statement), and path coverage (executing every path through the code). Statement coverage is not sufficient to catch all bugs, but path coverage tends to suffer from a combinatorial explosion of possibilities. Exhaustive path coverage may not be an option, but some weaker forms of path coverage are useful.

    Coverage testing clarification: "all possible paths" is impractical due to combinatorial explosion. "all nodes" is inadequate because it misses too much. The right compromise is "cover all edges".

    Example coverage tools:

    Clover
    This tool has been bought out and moved around, check out its video though
    Hansel
    A source forge tool; extension to JUnit
    Cobertura, Quilt, NoUnit, Jester, jcoverage, etc.
    Emma from the ever-popular Source Forge
    Where are (free) C++/Python/yourlanguage/etc. Coverage Tests?
    A couple more words on our sample coverage tools, Clover and Hansel. Clover is a commercial product which works by instrumenting the source code. It does statement and branch coverage, but not most of the other forms of coverage. It might actually be cool. Another commercial coverage tool is JCover, which does more types of coverage tests. There are no doubt dozens of others.

    Hansel is an open source extension to JUnit, based on code developed at the University of Oregon. It works with bytecode not source code. It appears to just do statement coverage. Its not much, but its free and its better than nothing.

    More on Coverage Testing

    Steve Cornett gives a nice summary of several kinds of coverage testing, including some reference to the different subsets of path coverage that have been proposed to make it practical. Note that although these are phrased as yes/no questions, a coverage tool doesn't just answer yes/no or even give you a percentage: it gives you a percentage and shows in detail each location or case in which the coverage property did not hold.
    statement coverage
    measure % of executable lines that were executed by the tests. A good starting point with many weaknesses. Examples:
    • not all of a short-circuit boolean expression may have been tested in 100% statement-coverage.
    • If an if statement has no else clause, 100% coverage does not include: is the "then" ever not taken?
    It is a challenge to even get this much coverage.
    function coverage
    did you execute every function? Weaker than statement coverage, but maybe easier. Function coverage would reveal if a function / interface was totally broken. Examples:
    • test that shared library entities are callable.
    • catch method body stubs designed to blow up, and spectacular errors
    call coverage
    did you execute every (expression where there is a) call to every function? Seemingly weaker than statement coverage, except that there can be calls that are skipped by short-circuits.
    loop coverage
    did you execute every loop 0, 1, and >1 times? Complementary to and non-identical to statement coverage. What other coverages might you invent that are similar to loop coverage?
    relational coverage
    did you test every relational operator with equal, lesser-, and greater-than values, in order to avoid off-by-one errors and logic inversions? Expression-level coverage would be finer than statement level coverage. Certain aerospace and military standards would require this level.
    data coverage
    did every variable actually get referenced? every array element? was every pointer followed? (Thought question: what kinds of bugs might this coverage help find?)
    decision coverage
    evaluate every (outermost level) boolean expression to both true and false. a.k.a. branch coverage. May find things missed in statement coverage (for example, the proverbial check-if-then-part-is-skipped), but still doesn't cover short circuit code
    condition coverage
    check whether individual boolean subexpressions were evaluated to both true and false. This is "micro" or "atomic" scale coverage. Will detect if short circuits are being skipped. Does not guarantee decision coverage!?
    multiple condition coverage
    check whether all possible combinations of boolean subexpressions were executed. Effectively, it is small-scale (statement- or expression-level) path coverage. Scoring well requires a lot of test cases.
    condition/decision coverage
    union of condition coverage and decision coverage
    modified condition/decision coverage
    verify every condition can affect the result of its encompassing decision. If it can't, why is it in the code? Likely a logic bug. By definition, short-circuit conditions fail this test. Invented at Boeing; required for certain aviation softwares.
    path coverage
    check if each possible paths in each function have been followed. A path is a unique sequence of branches from function entry to exit. Loops introduce an unbounded number of paths. # of paths is exponential in the number of branches. Some paths may be impossible. Many many variations introduced to try and develop "practical" path coverage methods.
    A couple other useful resources are Marick's a Buyer's Guide to Code Coverage Terminology, and the related How to Misuse Code Coverage.

    Software Project Estimation

    Probably this material belongs in CS 383. I am moving it there in future. I looked at websites for some of this material, in addition to consulting Roger S. Pressman's book on software engineering.

    COCOMO

    Boehm's COnstructive COst MOdel. Barry Boehm is one of the luminary founding fathers of software engineering, inventor of the spiral model of software development, and one of the early predictors that software costs would come to dwarf hardware costs in large computer systems.

    COCOMO is acronym-laden, and subject to perpetual tweaking and twisting of its interpretation. Whatever I give in lecture notes about it will contradict various COCOMO authoritative sources.

    COCOMO starts from an estimate of SLOC (source lines of code). This includes declarations, but no comments, no generated code, no test drivers). Boehm also refers to KDSI (thousands of delivered source instructions) and it appears to be used more or less interchangeably with SLOC.

    Scale Drivers

    COCOMO specifies 5 scale drivers:

    Cost Drivers

    COCOMO has ~15 parameters that assess not just the software to be developed, they assess your environment and team as well. They are rated one of: (very low, low, nominal, high, very high, extra high), with the different values contributing multipliers that combine to form an effort adjustment factor. From Wikipedia:
    Cost Drivers Ratings
    Very Low Low Nominal High Very High Extra High
    Product attributes
    Required software reliability 0.75 0.88 1.00 1.15 1.40  
    Size of application database   0.94 1.00 1.08 1.16  
    Complexity of the product 0.70 0.85 1.00 1.15 1.30 1.65
    Hardware attributes
    Run-time performance constraints     1.00 1.11 1.30 1.66
    Memory constraints     1.00 1.06 1.21 1.56
    Volatility of the virtual machine environment   0.87 1.00 1.15 1.30  
    Required turnabout time   0.87 1.00 1.07 1.15  
    Personnel attributes
    Analyst capability 1.46 1.19 1.00 0.86 0.71  
    Applications experience 1.29 1.13 1.00 0.91 0.82  
    Software engineer capability 1.42 1.17 1.00 0.86 0.70  
    Virtual machine experience 1.21 1.10 1.00 0.90    
    Programming language experience 1.14 1.07 1.00 0.95    
    Project attributes
    Use of software tools 1.24 1.10 1.00 0.91 0.82  
    Application of software engineering methods 1.24 1.10 1.00 0.91 0.83  
    Required development schedule 1.23 1.08 1.00 1.04 1.10  

    COCOMO equations 1 and 2

    Effort = 2.94 * EAF * (KSLOC)E
    Time_to_develop = 2.5(MM)0.38

    where EAF is an Effort Adjustment Factor derived from cost drivers, and E is an exponent derived from the 5 scale drivers. EAF defaults to 1 and E defaults to 1.0997. But since these are parameters, it is largely the structure of the equation that matters.

    Example: Average? 8KSLOC? Then effort = 2.94 * (1.0) * (8)1.0997 = 28.9 person-months

    Calculators:

    Pithy Software Engineering Quote of the Day

    Design without Code is just a Daydream. Code without Design is a nightmare."
    -- attributed to Assaad Chalhoub, adapting it from a Japanese proverb.

    Estimating SLOC

    Basic ideas summarized: you can estimate SLOC from a detailed design, by estimating lines per method for each class, and summing. Or you can do it (possibly much earlier in your project) by calculating your "function points" and estimating lines-per-function-point in your implementation language.

    Function Points

    Perhaps this might be the 2nd type of thing you measure about a forthcoming or under-construction software project (after "# of use cases"). Weight each of these; perhaps just designate as "simple", "average", or "complex".

    Sum of weights = "function points" of program.

    Inspections

    Idea: examine source code looking for defects.

    Roles:

    author
    moderator
    runs the meeting. establishes and enforces the "rules"
    secretary
    recording defects when they are found
    paraphrasers
    step through the document, explaining it in their own words

    Usability Testing (Bruegge 11.4.2)

    Three types of usability tests:
    scenario test
    give users the vision, see how difficult it is for users to understand the scenario.
    prototype test
    vertical prototype would do one whole use case in detail. horizontal prototype would do one layer (say, UI, without underlying functionality)
    product test
    use a functional version of the system. only available after it is implemented, but oh by the way, output of usability test will tell you possibly many or major things to revise in your user interface. (CS majors are not always good at usability!)

    state-based tests

    Developed for OO systems. Compares end-states of the system after a set of code is executed, instead of comparing outputs. Derive test cases from a UML statechart. Test every transition in the statechart. See Figure 11-14.

    State-based testing is harder than it would seem; it is hard to automatically generate the inputs needed before the test that are to put the system in the state needed in order to test a given transition.

    polymorphism and testing

    If you use "virtual" methods and/or polymorphism, how does it affect your testing strategy? Need to execute a given polymorphic code with all of its possible runtime types. Example (Fig 11-15): your network interface has open/close/send/receive methods, it is an abstract class with several concrete implementations. Test the clients that use the network interface against each of the concrete implementations.

    From Use Cases to Markov Chains to Software Testing

    This section is inspired by Axel Krings, who referred me to a paper by James Whittacre and Jesse Poore. Suppose you layout a finite state machine of all user activity, based on your use cases. You can estimate (or perhaps empirically observe) the probabilities of each user action at each state. If you pretend for a moment that the actions taken at each state depend only on being in that state, and not how you got there, the finite state machine is a Markov chain. While user actions might not really follow true Markov randomness properties, the Markov chain can certainly be used to generate a lot of test cases automatically!

    Integration Testing

    There are several ways to test combinations of units.

    Big Bang

    The "big bang": what happens when you link it all together? This has the advantage of not requiring any additional test stubs that would be needed to test partially integrated subsystems. But when things go wrong, you have a needle in a haystack problem of finding the bugs.

    Top Down

    Top down = work from the user interface gradually deeper into the system. This is a layered, breadthfirst approach. Advantage: it is more "demo-able" for customers. Subsets of functionality may become usable before the whole system integration is completed.

    Bottom Up Testing

    Bottom up = test individual units first
    Focus on small groups (2+) of components. Add components gradually. Advantage: it is more debuggable and emphasizes meat-and-potatoes over shallow surface behavior.

    Sandwich Testing

    Sandwich testing selects a "target layer" and tests it against the layers above and below it. New target layers are selected to generate additional tests until the whole system has been tested. If the target layers are selected to gradually work from top and bottom into the middle, then sandwich testing is a combination of top-down and bottom-up testing.

    Questions:

    Lecture 12

    Phunctional

    Went Well:
      well organized, got sprint report done quickly
    • majority of coding going as planned
    Needs Improvement:
    • group meeting lacks goals/direction
    • division of labor needs to happen before Thursday
    Plans for this sprint:
    • tasks assigned: 5 on code, 3-4 on critical path code
    • saving xml
    • fixing dialog stuff
    • interaction diagrams + docs
    • Hg plugins, misc

    Pummel

    Went Well:
    • more organized, presentation better
    • Thursday meeting more productive
    Needs Improvement:
    • make sure everyone is OK with Mercurial
    • find an extra meeting time
    Plans for this sprint:
    • figure out how to handle interactions with things not in another diagram
    • pair programming assignments were made: david/adrian lines, theora/austin shapes, alex/coleman scaling+ordering zvalue, jason/cable on tabs.

    Build report

    cd puml && hg update
    abort: untracked file in working directory differs from file in requested revision: 'doc/ssrs/ssrs.aux'
    ...
    
    Please remove ssrs.{aux,log,pdf,toc} from repository, LaTeX generates them.

    Unit Testing, Revised

    Wikipedia says we have a lot of Unit Test tools to choose from, which do we use? So far the recommendation was CppUnit or QtTest. You are welcome to evaluate and select something else if it has technical advantages to you.

    Test Plans, Revisited

    HW2 part 2 asked you to develop a test plan, and create a doc/384-hw2.html that would presumably include links to both your gantt or pert chart, and your test plan.

    Q: how were you supposed to do a test plan when we hadn't talked about various kinds of software testing yet, and you'd only been given a preliminary description of what a test plan is? This kind of thing occurs over and over again when agile/spiral methods mix in with traditional IEEE Standard (waterfall-style) documentation expectations.

    A: Your job includes: ask questions, read lecture notes, take a first stab at a "test plan", and refine from there, with feedback. As for the whole waterfall-documents-in-a-spiral-world thing, we should iteratively create and refine documents like we do code, each sprint including coding goals, testing goals, and documentation goals. At the end of the semester, or preferably sooner, we should have accomplished the full set of documents and code for the whole project.

    Jeffery's conjecture:

    Customers will only buy-in to a newfangled development process when they see it gives them some convincing combination of more control, better quality, and/or less cost. Agile methods may focus more on customer and product than on documentation, but documentation remains a key element in communicating with the customer.

    Now, let's take a second pass at Test Plans. Here is a Test Plan Template based on Latex source.

    System Testing

    Tests the whole system. There are many kinds of system tests.

    Functional (requirements) testing

    Looks for differences between the requirements and the system. This is traditional blackbox testing. Test cases are derived from the use cases. Try to create test cases with the highest probability of finding the bugs the customer will care about the most.

    Performance testing

    This tests one of the non-functional requirements. Typically, a system will be tested to see if it can handle the required userload (stress test) with acceptable performance...which may require a fairly elaborate fake user environment; consider what it would take to test how a web server handles lots of hits.

    Other forms of performance testing include volume testing (how does the system handle big input datasets), security testing (by "tiger teams" ?), timing tests, recovery tests (e.g. artificially crash the network or other external resource).

    Pilot test

    Also called "field test", these tests may go out to a progressively larger number of real customers.
    alpha test
    Features are frozen for a pending delivery. Extensive in-house testing that tries to simulate an end-user experience. Bug reports come in and are fixed furiously. Often a crunch time-causer.
    beta test
    Features remain frozen. Software is delivered/installed/operated on end-user hardware, with "friendly" customers who agree to provide detailed bug reports.
    • closed beta - beta customers are hand-selected ("by invitation")
    • open beta - beta customers are self-selecting ("masochists")

    Testing Odds and Ends

    We will probably scratch our way through a few more testing topics as needed in future lectures.

    Acceptance test

    Benchmark tests, possibly against competitors or against the system being replaced (shadow testing). A specialized team from the customer may be involved in the evaluation of the system.

    Installation test

    Anytime you install a program on a new computer, you may need to verify that the program is running in the new environment. Software is often shipped with a self-check capability, which might run when first installed and then disable itself. More paranoid software self-checks every time it is executed, or even periodically during execution.

    Managing test activities

    Planning the testing process

    Start the selection of test cases early; parallelize tests. Develop a functional test for each use case. Develop test drivers and stubs needed for unit tests. Some expert (Bruegge?) says to allocate 25% of project resources for testing -- do you agree?

    Midterm is Coming

    It is time to set a Midterm Examination date. The midterm will be Monday February 27, following a self-study / online review on Friday February 24. The midterm will cover aspects of software testing and mapping UML to code. Read up, or better yet, do and ask questions.

    How is your Unit Testing Going?

    Do you ALL by now have some experience unit testing, and have some tangible test driver code to show for it? If anyone thinks they do not, ask your teammates to help you find what to work on, or report to Dr. J for advice or reassignment.

    Milestones

    We want successively more accurate and more complete functional approximations of the Gus project requirements document(s). I would more or less like to see explicit sets of use cases attached to specific milestone dates for demos in class. It is possible that some use cases might be broken up into multiple milestone dates and deliverables, but for the most part, use cases define the usable pieces of functionality of your system.

    Where we are At, Where we are Headed

    You are, hopefully, in the heat of coding your project. We are doing homeworks that mainly address this from a testing point of view. Dr. J is trying to penetrate the fog of war and understand what you are doing, without imposing too many extra and onerous tasks on you.

    At Microsoft there used to be the mantra:

    Windows isn't done until Lotus won't run.
    In software engineering class, we could have a highly unrelated and less catchy saying
    the work is not done until it is documented, findable (i.e. by Dr. J navigating in the repository) and reproducible (i.e. others can build/run/test successfully, not just the author).

    The concept of literate programming

    Donald Knuth, one of the Vampire Mega-Lords of the computer science world, proposed the more-or-less radical concept of literate programming. While his concept has not taken the softare engineering field by storm, it raises many valid issues. Knuth's solution (literate programming) is to write a hybrid document that can be translated into either a book for humans to read, or a source code base for a compiler to compile.

    Why bring it up here and now? Because Dr. J has to be able to read and understand your code repository in order to grade it. What do I need? Maybe not literate programming, but a clear, explained codebase.

    What would that look like?
    Not just JavaDoc/Doxygen/PyDoc etc, although their use does help.
    What more?
    Big picture code description, table of contents, connections back to design and requirements.
    How to present it?
    Via a set of index.html files that explain and link all the source codes together?

    No Class Monday

    It is a Federal and UI Holiday.

    Myers' Checklist for Code Inspections

    Figures 3.1 and 3.2 of [Myers] give a list of low-level things to look for.
    1. Unset variables used?
    2. Subscripts within bounds?
    3. Noninteger subscripts?
    4. Dangling references?
    5. Correct attributes when aliasing?
    6. Record and structure attributes match?
    7. Computing addresses of bit strings? Passing bit-string arguments?
    8. Based storage attributes correct?
    9. Structure definitions match across procedures?
    10. String limits exceeded?
    11. Off-by-one errors in indexing or subscripting operations?
    Data Reference Computation
    1. Computations on nonarithmetic variables?
    2. Mixed-mode computations?
    3. Computations on variables of different lengths?
    4. Target size less than size of assigned values?
    5. Intermediate result overflow or underflow?
    6. Division by zero?
    7. Base-2 inaccuracies?
    8. Variable's value outside of meaningful range?
    9. Operator precedence understood?
    10. Integer divisions correct?
    Data Declaration Comparison
    1. All variables declared?
    2. Default attributes understood?
    3. Arrays and strings initialized properly?
    4. Correct lengths, types, and storage classes assigned?
    5. Initialization consistent with storage class?
    6. Any variables with similar names?
    1. Comparisons between inconsistent variables?
    2. Mixed-mode comparisons?
    3. Comparison relationships correct?
    4. Boolean expressions correct?
    5. Comparison and Boolean expressions mixed?
    6. Comparisons of base-2 fractional values?
    7. Operator precedence understood?
    8. Compiler evaluation of Boolean expressions understood?
    Control Flow Input/Output
    1. Multiway branches exceeded?
    2. Will each loop terminate?
    3. Will program terminate?
    4. Any loop bypasses because of entry conditions?
    5. Are possible loop fallthroughs correc?
    6. Off-by-one iteration errors?
    7. DO/END statements match?
    8. Any nonexhaustive decisions?
    1. File attributes correct?
    2. OPEN statements correct?
    3. Format specification matches I/O statement?
    4. Buffer size matches record size?
    5. Files opened before use?
    6. End-of-file conditions handled?
    7. I/O errors handled?
    8. Any textual errors in output information?
    Interfaces Other Checks
    1. Number of input parameters equal to number of arguments?
    2. Parameter and argument attributes match?
    3. Parameter and arguments UNIT SYSTEMS match?
    4. Number of arguments transmitted to alled modules equal to number of parameters?
    5. Attributes of arguments transmitted to called modules equal to attributes of parameters?
    6. Units system of arguments transmitted to called modules eual to units system of parameters?
    7. Number, attributes, and order of arguments to built-in functions correct?
    8. Any references to parameters not associated with current point of entry?
    9. Input-only arguments altered?
    10. Global variable definitions consistent across modules?
    11. Constants passed as arguments?
    1. Any unreferenced variables in cross-reference listing?
    2. Attribute list what was expected?
    3. Any warning or informational messages?
    4. Input checked for validity?
    5. Missing function?







    Source: Glenford [Myers], "The Art of Software Testing".

    How do we normalize class participation?

    It is typical in 383 and 384 that some folks are doing far more of the work than others. This can be for any number of reasons, some more sympathetic than others. Basic goals:

    Software Metrics

    Software metrics, or measurement, concerns itself with observing properties of a software system. Engineers really want In addition, the engineers' managers often want to validate / justify what the team is doing, i.e. argue that they are using good or best methods.

    Metrics Taxonomy

    Dimension 1: static vs. dynamic. Are we measuring properties of the source code or .exe (products)? Properties of the execution(s) (resources)? Properties of the development activity (processes)?

    Dimension 2: direct vs. indirect. Are we measuring things that are objectively observable, or do we want to put a number on something more abstract (typically, the *-"lities")? Exercize: how many "lities" can you think of? How would you measure each?

    Phunctional

    went well
    demo went well, reached milestone,
    needs improvement
    random functional features should have been done
    this sprint
    pair programming, statechart implemented per current use case diagrams, start work on other types, continue to work on hw, *update backlog

    Pummel

    went well
    finally got everyone repo'ing, demo was ready, pair programming
    needs improvement
    make milestones a larger priority, prepare for meetings!!
    this sprint
    work on connectors, textboxes associated with objects (labels, etc), I/O, fixing objects/shapes worked on last week, wiki updates,

    Why Define Software Metrics?

    If we are ever going to "engineer" software, we have to have the underlying science on which to base the engineering. Sciences are all about explaining the data. Sciences are all about tying the data to underlying principles. Scientists measure and observe things. Software Metrics are a step towards placing software on a scientific basis.

    But How do we Define the Right Software Metrics?

    Say we want to measure Quality.
    • What units can we use?
    • For example, does Quality = #bugs / #KLOC ?
    Definitions have been proposed for many or most of the *-"ities".

    Size-oriented, direct measures

    • lines of code
    • execution speed
    • memory size
    • bug reports per customer-week

    Function-oriented, indirect measures

    • "function points" -- how much functionality has been built/delivered
    • quality
    • complexity -- missed this one on Monday
    • efficiency
    • reliability
    • maintainability
    Build Check: pUML
    • cloned onto Linux Mint 12 machine in my office
    • installed Qt and build per instructions in README
    • warnings in {mainwindow,nodes,dialog}.cpp, fix by Monday.
    • README says ./pUMLTest2 but I had only pUML (fix README?)
    • remove debugging print statements ("here", "usecase") from commit
    • surprised I couldn't drag usecase after creation, blue squares misled me.
    Build Check: pummel
    • Add a top level README with build instructions, and/or comply with semi-universal open-source standards (makefile and/or configure script)
    • README in src/ directory is good, thanks :-)
    • README says you are using an older Qt; I will not go looking for older versions so upgrade or ensure compatibility with 4.7.4
    • have a makefile rule that will do stuff like invoking qmake and sed
    • Probably want to have "compilable/executable stubs" in place rather than filtering things from the project file.
    • warnings in {dragitem,dragscene,ellipse}.cpp, fix by Monday.
    • fatal error OptionsDialog.h no such file, fix by Friday

    Metrics in Bruegge

    Bruegge says precious little about software metrics. He mentions management metrics versus quality metrics. Management metrics might include how many development tasks have been completed, how much $ has been spent, team turnover rates... Quality metrics might include change requests per week, defects discovered per test-hour or test-week, how much code is changed per week ("breakage"? "rework"? "flux"?).

    Some "-ities" Bruegge mentions are stability, modularity, maturity. Suppose one wants to measure some of these, or some of the nice ones you came up with in class -- how do you put a number on them? If project A has a "maturity score" of 1.7 and project B has a score of 3.4, does that mean project B is "twice as mature" as project A?

    Simplified Notes from Fenton's Software Measurement: A Necessary Scienfic Basis

    Skipping most of the high powered math...

    Measurement Relations and Scale Types

    There are many, many ways to assign numbers to an attribute with varying degrees of numeric validity.

    Given two (of many) measurement systems M and M' that we could use to measure a property of our software, how do we compare them? If we were comparing a measure in feet (M) with a measure in meters (M'), there would be some constant c such that M=cM' (for height, every reasonable measurement units would be convertible into every other, so the measurement of height uses a ratio scale type).

    We want measure M(x) to preserve relations such that, for example, M(x) < M(y) is equivalent to some underlying true relation R between x and y. Don't define a measure unless you understand the empirical relations (the scale type) for the attribute you are measuring.
    Scale Type Comment
    nominal "values" are names; measures can be compared if their names can be mapped onto each other
    ordinal values can be compared, but no origin or magnitude can be assured
    ratio values use a different scale
    difference values use a different origin (Celcius v. Kelvin)
    interval different origin and unit scale (Celcius v. Fahrenheit)
    absolute (directly observed property)
    log-interval values are exponentially related
    This comes back to explain the topic of scale types mentioned last lecture.

    Metrics in the Java World?

    JMT
    Java metrics freeware from Magdeburg.
    PMD
    Cool sourceforge project, kind of like "lint", but oh by the way it calculates cyclomatic complexity.
    cyvis
    A tool mentioned in a nice article about cyclomatic complexity.
    Mebbe I just need to assign you homework (in your spare time, on the side) to try these tools out and report which ones give useful information. Now, what about C++?

    Metrics for our project?

    What metrics do we need? How do we measure them?
    ls -l ...
    # of files, beware miscounting
    wc ...
    # of ASCII lines, but doesn't count executable statements
    (svn|hg|...) log ...
    lots of information about actual commits

    Inspections

    Metrics I Want

    I am thinking about Software Metrics as part of the project management/evaluation process, which blurs the line between grading (which I do) and documentation (which you do).

    I want to measure:

    • how "big" our projects are
    • how much of our functionality is implemented
    • how much of our code is tested, how tested is our code
    • who did the work?
    • what are our problem areas?

    Thought exercise: how do we measure each of these? How much work will it take?

    lecture 17

    CCCC Report #1

    CCCC was part of Tim Littlefair's Australian Ph.D. project. It generates webpages. It collects a number of metrics. It appears to be readily available on Linux (easy install on my Mint 12 machine in my office). Questions on my mind include: What information does it pull out? Does it appear useful? What potential uses might it be applied to? Do you need a Ph.D. to interpret it? Do you need to read a big manual to interpret it?

    Sprint Meeting Notes

    Pummel

    went well
    pair programming, pre-presentation meeting, wikipage/updates page
    needs improvement
    repository issues, update wiki page more often.
    for next sprint (weds after spring break)
    textboxes, baseline class, "majority" of objects, rework test cases to match/reflect use cases

    Phunctional

    went well
    pair programming, statechart diagram "mostly" complete
    needs improvement
    repository glitches, homework delayed, other diagram types
    for next sprint (weds after spring break)
    getting rest of diagram types to work, collab shapes, object ordering, toolbar filtering, XML, documentation, unit tests

    lecture 18 starts here

    Midterm Exam Discussion Grading still in progress. We will discuss sample solutions.

    Doomsday Speech

    As far as I can tell from demos and looking at the Mercurial repositories:
    one team is rather far behind the other team, which will adversely impact its average grades at end-of-semester if the gap remains
    ...but the team that is not behind cannot afford to coast
    success at end-of-semester is not based on just giving a cool demo
    SE grade based largely on code, tests, measures, and documentation
    both teams haven't planned their testing much, or I am not seeing where
    somewhat understandable, but we need plan for unit testing, plan for integration testing, plan for system testing... and clear documentation of what testing got done when finished.
    I hope your gantt/pert planning has you finished coding Real Soon
    planning to keep on coding through April means planning to not test adequately, and planning to not have stabilized anything before grading

    12 principles that guide programming at Google

    Ask yourself "which of these are agile methods?" and "would any of these improve our team's effort?"
    1. All developers work out of a more-or-less single source depot; shared infrastructure!
    2. A developer can fix bugs anywhere in the source tree.
    3. Building every google product takes the same 3 commands ("get, config, make")
    4. Uniform coding style guidelines across company
    5. Code reviews mandatory for all checkins
    6. Pervasive unit testing, written by developers
    7. Unit tests run continuously, email sent on failure
    8. Powerful tools, shared company-wide
    9. Rapid project cycles; developers change projects often; 20% time
    10. Peer-driven review process; flat management structure
    11. Transparency into projects, code, process, ideas, etc.
    12. Dozens of offices around world => hire best people regardless of location

    A "Weak Tests" Hypothesis

    In a past semester, a student provided an excellent hypothesis for why some of the tests in some of the homeworks have been missing or trivial. That student said the reason there aren't tests in many cases is because the code isn't done -- meaning not written at all, or not finished enough to test, anyhow. After all, how can you write tests if you don't have the code written yet?

    Of course, eXtreme Programming (XP) advocates do in fact tell you to write the tests before coding. Our HP advisory board member has been very... adamant about wanting us to figure out how to do this.

    Observation: it is quite possible to write black box tests ahead of time, but whitebox tests can't be written until there is code. So, are your "unit tests" black box tests, or whitebox tests, or both?

    Corollary: testing can be included in the spiral model, and multiple iterations of increasing testing go along with multiple iterations of increasing code functionality.

    What Do Integration Tests Looks Like?

    A set of integration tests would: Note that from http://hissa.nist.gov/HHRFdata/Artifacts/ITLdoc/235/chapter7.htm there is a good observation, relevant to integration testing: as component/subsystem size increases, coupling among sibling components should decrease. If a system design follows this principle, most integration tests will be near the leaf units.

    What does an end-user system test look like?

    Consider this fragment from the Unicon checklist.

    Software Complexity

    Why measure? Because code that is too complex is more buggy and more expensive to maintain.

    Potential downsides: rewriting to reduce a particular complexity metric may just move the complexity around, into unmeasured areas. For example, one can reduce "cyclomatic complexity" internal to methods by writing more methods, but does that help>

    Halstead's "Software Science"

    One of the older proposed measures of software complexity takes almost an information-theoretic approach, and measures complexity in terms of some low-level, observable properties of the source code, in particular from the following direct metrics: Halstead defined the following metrics: From all this

    Strengths: scales well; can be applied to whole programs with about the same effort as individual functions/methods. Some information-theoretic validity. May actually give very high level languages their claimed benefit of being "higher level".

    Weaknesses: software science seems to be voodoo. "Volume" and "potential volume" definitions seem to be just made up numbers. The program level #'s might not have a stable scale type, to where you can say that a number of .5 or above is "good" and below .5 is "bad". Doesn't acknowledge control or data flow paths as being fundamental to complexity.

    (finish discussing Halstead's software science)

    McCabe's Cyclomatic Complexity

    Given a flow graph G, the # of cycles (cyclomatic number) will be
    v(G) = e - n + p
    where e=#edges, n=#nodes, and p=#connected components.

    McCabe wanted a complexity measure

    Before McCabe came along, major corporations had been having gigantic problems with overly complex subroutines, so the point where they had instituted maximum size limits, such as each subroutine may have at most 50 lines (IBM) or two pages (TRW). McCabe's point was that such limits miss the boat: some nasty spaghetti may become overly complex in far fewer lines, while plenty of far larger routines are not complex at all and forcing them to be broken into pieces by arbitrarily limiting their size only complicates and slows them down.

    Note that although the cyclomatic complexity of a whole program is the sum of all the subroutines and may go very high, McCabe was not worrying about whole program complexity, he was only worried about individual routine complexity, so in applying his measure to our whole system we should be interested in the maximum, and the distribution, of the individual routines' complexity, not the sum.

    A Skeptic's Testimony

    Richard Sharpe's comments on McCabe Cyclomatic Complexity: the proof in the pudding.

    McCabe and OOP

    A student once asked how McCabe applies to OOP programs with complex interconnections of objects. One answer was that cyclomatic complexity measures control flow complexity without measuring data complexity and is therefore incomplete, and that OOP systems often have a lot of data complexity. Another answer is that McCabe's metric is generally applied at the single function/method unit level, at which calls to subroutines are abstracted/ignored. Measuring the control complexity of Java is just as useful (in looking for red-flags) as in non-OO languages. A third answer is: OOP programs tend to be broken down into smaller functions, and so the individual functions' complexity may be lower (which is good), but there must also be a coarser-grained complexity measure for the call graph, and OO programs may have worse characteristics for that measure.

    Ez, practical cyclomatic complexity? PMD from sourceforge is said to be integrated into Netbeans, Eclipse, etc.

    In-class Exercise: calculate McCabe's complexity metric for an interesting project method you have written

    lecture 19 starts here

    Any Entrepreneurs?

    There is an interdisciplinary Entrepreneurship Certificate coordinated by the college of business. You get a certificate (which also appears on your official transcripts) if you complete introduction to entrepreneurship, enterprise accounting, and two CS courses: a CS tech elective and our 481 capstone, which you probably are taking anyhow. If any of you think you may want to do your own startup someday, it might be useful.

    Things to Include in Your Sprint Planning

    code inspection
    who is playing what role, and reviewers please read the code ahead of time
    tests and test plan
    unit-tests-only or undocumented (or undiscovered) testing would result in a "C" or "D" grade for your team on that part of your project grade. An "A" grade will have an overall test plan with supporting unit, integration, and system tests that make sense in your project context; I will be able to locate it and navigate well enough to see what was tested and believe what I saw to be thorough and appropriate. The culmination will include testing with one or more end-user groups, and time to incorporate some of their feedback.
    metrics and metrics plan
    This one is more collaborative in the sense that I am willing to help, but by the end of the semester, we want the project documentation to include a selection of appropriate metrics including static and runtime resources used, performance, software complexity and/or quality, and test metrics such as coverage. For an "A" grade, I will be able to read and believe that the metrics selected convey credible information about the size, scope, and utility of the completed system.

    A Few Thoughts on Measuring Complexity of our Projects

    McCabe - no one module probably has interesting McCabe #
    Halstead - we could use it, but wouldn't know what it means
    Class complexity - we could look for measures of this
    perhaps "association complexity" or "class diagram complexity"
    Coupling - we could measure this as an approximation of class complexity
    See http://www.sdml.info/library/Allen99.pdf
    Data structure complexity - if the data
    See ... Munson et all (to fill in)
    Pragmatics says focus on: tools for our project languages
    what metrics have the programming community already made handy for us?

    Software Quality

    What we have said so far: quality is probably not equal to #bugs/#KLOC. Probably not change requests or defect reports per week. Some folks say it is totally: how users perceive the software, how much value they obtain from it. Others argue quality might be a multiplied combination of normalized measures of the following properties.


    Understandability
    • definition: understandability is the opposite of "density"...the more expertise required to understand, the less understandable it is. Combination of comments, variable names, and (limits on) complexity
    • how to measure: subjective; peer review; walkthrough ratings; it's possible to measure/detect absence of comments, and possibly the use of poor variable names
    • how does it relate: Consistency helps understandability


    Completeness
    • definition: satisfies all the requirements; is fully commented
    • how to measure: blackbox observation? user satisfaction; lack of feature requests
    • how does it relate: lack of comments leads to lack of understandability (?)


    Conciseness
    • definition: functionality / code
    • how to measure: Function points / KLOC ?
    • how does it relate: more concise sometimes is more complex


    Portability
    • definition: a program is portable if it runs on multiple operating systems; if it fits on a flash drive? runs on different hardware? lack of CPU, word-size, compiler dependencies.
    • how to measure: count how many [CPU, OS, GPU, wordsize] combos you run on?
    • how does it relate: size/complexity may drive minimum requirements


    Consistency
    • definition: a program is consistent if it is formatted + commented consistently; consistently not-crashy; returns the same value of given the same input; API consistency (return values + params are similar across the interface); file/function/class names are predictable; consistent software design methods; consistent testing; consistent GUI
    • how to measure: peer review; look for absence of variations
    • how does it relate: reliability, testability


    Maintainability


    Testability
    • definition: a program is testable if it can be run in a batch mode; if various system states that need testing are recreatable artificially
    • how to measure: #people needed; amount of manual effort per test run; peer evaluate results from test runs; complexity required in order to automate tests
    • how does it relate:


    Usability
    • definition: a program is usable if end users have an easy learning curve; if a program can be run successfully by a moron; low # of keyboard or mouse clicks to accomplish a given task
    • how to measure:
    • how does it relate: GUI consistency; undestandability


    Reliability
    • definition: how often it needs maintenance? if it copes with errors without failing or losing a user's work
    • how to measure: MTTF; hours/months between failures
    • how does it relate: consistency of behavior


    Structured
    • definition: a program is appropriately structured if it uses data types proportional to the size / complexity of the application domain problems it must solve.
    • how to measure: look for excessive coupling; low cohesion; look for excessive numbers of idiot classes; look for monster/monolith classes
    • how does it relate: understandability; maintainability, ....


    Efficiency
    • definition: a program is efficient if results consume "minimal" memory, time, disk, or human resources to obtain.
    • how to measure: are we within epsilon of the optimal?
    • how does it relate: hyperefficient algorithms are often less understandable/maintainable than brute force algorithms


    Security
    • definition: a program is secure if it has no undocumented side effects? if it is impossible (or difficult?) for a program to give up information that is private; to give up control over computer resources to an unauthorized user
    • how to measure: how many minutes it takes a whitehat to hijack your application and use it to bring Latvia down off the net
    • how does it relate: complexity; usability

    Issues we ought to work on

    Option #1: brainstorm in-class.
    Option #2: graded homework assignment.

    Pummel

    Went Well
    productive over break, fixed repo issues, icon implemented
    Needs Improvement
    cable's laptop's VGA output, more realistic short term goals

    Phunctional

    Went Well
    got work done, progress on later milestones, website, installer
    Needs Improvement
    missed THIS SPRINT'S milestones, not force-pushing work over everyone else's, missing work on unit testing, need more portability testing before pushes

    Announcement
    Dr. J has to go to Seattle on Friday. Each team please meet, take attendance, and work on whatever is most needed for your sprint

    lecture #21 started here

    Feedback on Test Plan Prose

    I was asked for feedback on test plan documentation for the following.

    Integration Testing

    This is the phase where GUI events are tested. During this phase, all use cases will be walked through manually while confirming the correct events are invoked based on input. For these individual use case tests, each test must be run as independently as possible with minimal setup. This is to observe the behavior of each use case completely independent of the others.

    Functional Testing

    The functional phase is where usage of the UML editor is tested to a much higher degree. Rather than testing each use case individually, there will be a variety of users selected to attempt to produce UML diagrams of different types and magnitudes. This will produce a very large variety of permutations of use cases, and allow us to observe how the use cases behave when used together.

    Reflection

    Pummel

    went well:
    lines of code got written, communication, code review
    needs improvement:
    pre-sprint meeting prep

    Phunctional

    went well:
    test plan, statechart improvements, bug fixes
    needs improvement:
    didn't plan sprint report, didn't assign someone to bring a real computer

    Agile Methods Tips

    Gamedev.net once posted (associated apparently with gdc2010) an interesting article on agile methods, which has since disappeared into the ether. All we have left are the following observations about doing agile methods well. See if any will help in your remaining sprints.

    Project Watch

    Here's what I have (what am I missing?) for from git pulls as of 3/23/11

    Software Verification

    The process of checking whether a given system complies with a given criterion. One common criterion would be: check/confirm that the software complies with the design and that the design complies with the requirements. Some folks would narrow the definition to refer to a static analysis, that is, things that are checked without running the program.

    There is a whole field called Formal Methods which deals with constructing proofs of desired properties of programs. While historically these have been used only in safety-critical systems such as radiation therapy machines, or operating systems used in national security and defense hardware...there is a general trend toward reducing the cost of these methods which seems likely to end up in the mainstream someday.

    Example Verification Tools:

    ESC/Java2
    ACL2
    Zed, with real-world examples
    John Carmack on static analysis tools for C++.

    Software Validation

    Validation is related to verification, but it generally refers to a process of runtime checking that the software actually meets its requirements in practice. This may include dynamic analysis.

    Validation Testing: an old example

    Prologue: This is approximately what I learned about testing from a university, so according to Kaner, it should not be useful, or I should not have learned anything from it.

    The Unicon test suite attempts to validate, in a general way, the major functions of the Unicon language; it is used by folks who build Unicon from sources, especially those who build it on a new OS platform. The unicon/tests/README file divides the testing into categories as follows:

    The sub-directories here contain various test material for
    Version 11.0 of Unicon and Version 9.4 of Icon.
    
    	bench		benchmarking suite
    	calling		calling C functions from Icon
    	general		main test suite
    	graphics	tests of graphic features
    	preproc		tests of the rtt (not Icon) preprocessor
    	samples		sample programs for quick tests
    	special		tests of special features
    

    Each subdirectory has a suite of tests and sample data, and a Makefile for building and running tests. The master test/Makefile automates execution of the general and posix tests, which are routinely run on new Unicon builds. The general/ directory contains tests "inherited" from the Icon programming language (50 files, 5K LOC):

    augment.icn   collate.icn   gc1.icn	 mem01c.icn   prefix.icn  struct.icn
    btrees.icn    concord.icn   gc2.icn	 mem01x.icn   prepro.icn  tracer.icn
    cfuncs.icn    diffwrds.icn  gener.icn	 mem02.icn    proto.icn   transmit.icn
    checkc.icn    endetab.icn   helloc.icn	 mffsol.icn   recent.icn  var.icn
    checkfpc.icn  env.icn	    hellox.icn	 mindfa.icn   recogn.icn  wordcnt.icn
    checkfpx.icn  errors.icn    ilib.icn	 numeric.icn  roman.icn
    checkx.icn    evalx.icn     kross.icn	 others.icn   scan.icn
    ck.icn	      fncs.icn	    large.icn	 over.icn     sieve.icn
    coexpr.icn    fncs1.icn     meander.icn  pdco.icn     string.icn
    
    Some of these tests were introduced when new language features were introduced and may constitute unit tests; many others were introduced when a bug was reported and fixed (and hence, are regression tests). A semi-conscious attempt has been made to use pretty much every language feature, thus, the test suite forms somewhat of a validation of a Unicon build.

    The tests are all run from a script, which looks about like the following. Each test is run from a for-loop, and its output diff'ed against an expected output. Some differences are expected, such as the test which prints out what operating system, version and so forth.

    for F in $*; do
       F=`basename $F .std`
       F=`basename $F .icn`
       rm -f $F.out
       echo "Testing $F"
       $IC -s $F.icn || continue
       if test -r $F.dat
       then
          ./$F <$F.dat >$F.out 2>&1
       else
          ./$F </dev/null >$F.out 2>&1
       fi
       diff $F.std $F.out
       rm -f $F
    done
    

    Sample test (diffwrds.icn):

    #
    #          D I F F E R E N T   W O R D S
    #
    
    #  This program lists all the different words in the input text.
    #  The definition of a "word" is naive.
    
    procedure main()
       words := set()
       while text := read() do
          text ? while tab(upto(&letters)) do
             insert(words,tab(many(&letters)))
       every write(!sort(words))
    end
    
    Sample data file (diffwords.dat):
    procedure main()
       local limit, s, i
       limit := 100
       s := set([])
       every insert(s,1 to limit)
       every member(s,i := 2 to limit) do
          every delete(s,i + i to limit by i)
       primes := sort(s)
       write("There are ",*primes," primes in the first ",limit," integers.")
       write("The primes are:")
       every write(right(!primes,*limit + 1))
    end
    
    Sample expected output (diffwrds.std):
    The
    There
    are
    by
    delete
    do
    end
    every
    first
    i
    in
    insert
    integers
    limit
    local
    main
    member
    primes
    procedure
    right
    s
    set
    sort
    the
    to
    write
    

    What I Have Learned About Testing

    Remember, this was in an academic environment, so Kaner would dismiss it.
    • Software changes, so testing is largely about re-testing.
    • To reduce the cost of testing, Automate
    • Floating point numbers print out differently on different platforms
    • Not every difference between expected and actual output is a bug
    • Automated test scripts, as with make, are only as portable as your shell, but since test scripts aren't as complicated as a large system build process, test scripts are easier to reconstruct on odd platforms.
    • Automated test scripts only help when you use them.
    • Bug tracking systems only help when you use them. Putting them up and not using them is negative advertising.
    • Properties like "coverage" must be reestablished after changes
    • Graphics programs are harder to test. GUI sessions can be recorded, but its harder to "diff" two computer screens than two text files.
    • Testing is only half of the maintenance job: testing without bug fixing is like holding an election and then keeping the results secret and not using them.

    Software Certification

    • Loosely, some organization promises that some property has been checked.
    • Verification or validation performed by a third party who is willing to testify or make the matter part of public record.
    • Sometimes has an "insurance" aspect, sometimes not
    • People willing to pay for certification are often the same people who are willing to pay to prove a program is correct.
    • Certification doesn't prove anything, it just guarantees some level of effort was made to check something.
    Certification Examples:
    • Windows compatibility - application or device driver certification
    • Medical device certification
    • Avionics certification
    Certification of software usually includes certification of the process used to create the software. Certification of software is also often confused with certification of the people who write software.

    lecture #24 began here

    Where we are at

    Windows Certification

    This section does not refer to certification of computing professionals, but to certification of the software written by 3rd parties for use on Microsoft platforms. Comparable certifications for other platforms include

    M$ doesn't certify that your program is bug-free, but it may certify that your program was written using current standards and API's. The large body of software developers tends to prefer the status quo, while M$ has good reasons to try and force everyone to migrate to whatever is new and hot.

    The last time I noticed much about this, the public rollout to developers of a new forthcoming version of Windows included lots of talk about a new look and feel (you had to take advantage of it), and new installer protocols (you had to register your software in a particular way during installation so that the control panel would know how to uninstall you). If you were willing to jump through these relatively simple hoops in support of the M$ marketing push for their new OS, and then submit your software (and maybe pay a modest fee), they would certify you as Windows compatible, and you'd be eligible for subsidizing on your advertising fees as long as you advertise your M$-compatibility.

    The Windows 7 Software Logo Specification document can be downloaded free from Microsoft; it covers topics such as the following. Much of this was found in the Windows Vista logo specification document.

    security and compatibility
    follow user account control guidelines, support x64 versions of the OS, sign files and drivers, perform windows version checking, support concurrent user sessions, avoid running anything in safe mode, don't be malware and follow anti-malware policies.
    • .exe's include a manifest that says to run as the invoker, at the highest available access, or requires administrator privileges. Nobody by special people get elevated privileges.
    • no 16-bit code is allowed
    • if you depend on drivers, x64 drivers must be available; 32-bit application code is ok.
    • binaries must be signed with an Authenticode certificate
    • drivers must be signed via WHQL or DRS
    • version check can't autofail on increased Windos version #'s, unless your EULA prohibits use on future OS'es. Use the version checking API, not the registry key everyone uses.
    • app must handle multiple users/sessions unless they can't. 3D apps are a good example; maybe they don't work over the remote desktop connection
    • if app can't handle multiple users, it must write a nice message, not fail silently
    • sound from one user session should not be heard by another user
    • applications must support "fast user switching"
    • installing software should not degrade the OS or other applications
    • must use Windows Installer (MSI) and do so correctly
    • don't assume the installing user will be the running user. User data should be written at first run, not during the install.
    • Applications should be install in "Program Files" or AppData by default
    • Software must be correctly identified in "Software Explorer" (i.e. Add/Remove Programs)
    • don't repackage and/or install Windows resources yourself
    • don't reboot during installation; be "restart manager aware"
    • support command line installation
    • pass a number of "Application Verifier" tests; get Application Verifier from www.microsoft.com/downloads/
    • Windows Error Reporting must not be disabled; handle only exceptions that you know and expect
    • sign up to receive your crash data
    installation
    reliability
    If M$ certifies you, you are legally allowed to use their logo on your box. You have to re-certify each major or minor version in order to retain the logo.

    Web application certifications:

    Sprint Reflection

    Pummel:
    Went well:
    lines working, icon glitches, all folks getting started on unit testing
    Needs Improvement:
    meeting attendance, work faster, test plan collaboration

    Phunctional:

    Went well:
    test plan, test cases, file saves "mostly" completed,
    Needs Improvement:
    saving/loading all our attributes, SSRS failed to compile!
    For next Monday: Pummel:
    • everybody contributing to the test plan
    • icons unit testable
    • lines deselection working, finish line types
    • everybody running unit tests
    Phunctional:
    • assigning/running tests
    • finish saving/loading
    • fixing the resizing of class boxes on Linux

    QSRs and CGMPs

    Software Engineers run into these certification requirements mainly when writing software for use in medical devices.
    FDA tends to be picky about instruments that will be used on humans
    a natural result of centuries of no regulation and many horrible deaths and maimings.
    FDA estimates that medical errors kill 100,000 Americans and injure another 1.3M each year. Woo hoo!
    Even with current regulations in place
    Testing "samples" gave way to testing the manufacturing process (for us: the software process) and the test environment.
    "Samples" (the old way) could mean: random samples of instruments or foods or software test runs.

    Definitions

    cGMP
    (current) Good Manufacturing Practice. not specific to software. documentation of every part of the process. Your food or drug can be 'adulterated' even if its not in violation of any specific regulatory requirement, if your process is not using cGMP. See also the wikipedia entry: cGMP
    QSR
    Quality System Regulation. Needs a formal quality system and quality policy. It must be audited, an improvement cycle needs to be documented. A software development lifecycle model (from among well known standards) must be documented. Safety and risk management must be a documented part of the software process.

    Intro to DO-178B (thanks to J. A.-F.)

    Software Considerations in Airborne Systems and Equipment Certification, published by RTCA and jointly developed with EUROCAE. As near as I can tell RTCA is an industry consortium that serves as an advisory committee to the FAA. At this writing RTCA charges $160 for the downloadable e-version of DO-178B; I guess they are profiteering from public information, despite their non-profit status. UI pays money every year to be a member, and I can access a copy free but can't share it with you. So... which category your software gets labeled determines how much testing, verification, validation, or proof gets applied to it. I hope the labeling is correct!

    Data Classification (CC1 and CC2) - what, you mean software certification includes certification of the data?! Well, we are used to some data being checked. Baselines, traceability, change control, change review, unauthorized change protection, release of information...

    How much independence is required during certification? Depending on your level, some objectives may require external measurement, some may require thorough internal (documented) measurement, and some may be left up to the discretion of the software developer (e.g. for level "E" stuff).

    DO-178B Required Software Verification:

    structural coverage testing
    test at the object code level. test every boolean condition.
    traceability
    requirements must be explicitly mapped to design must be explicitly mapped to code. 100% requirement coverage. requirements based test tools.

    DO-178C

    As of December 2011, a successor to DO-178B was approved which retains most of the text of the DO-178B standard, while updating it to be more amenable to

    How to be Certifiable

    There is "Microsoft certified" and "Cisco certified", which usually refers to passing an expensive test that covers a specific set of user tasks on a specific version of software... this is the kind of certification you'd expect to get from "Lake Washington Vocational Technical School".

    But...there is also the title: IEEE Computer Society Certified Software Development Professional and the forthcoming title: Certified Software Development Associate.

    Mostly, the big and expensive test may make you more marketable in a job search or as an independent software consultant. It is loosely inspired by the examination systems available for other engineering disciplines. It covers the SoftWare Engineering Body of Knowledge (SWEBOK), a big book that sort of says what should be covered in classes like CS 383/384. Any teacher of such a course has to pick and choose what they cover, and the test let's you fill in your gaps and prove that you are not just a Jeffery-product or UI-product, you know what the IEEE CS thinks you need to know.

    One more certification example

    Courtesy of Bruce Bolden, please enjoy this certification from codinghorror.com

    Planning:

    In addition to your own prioritized task assignments, please consider:
    • which university group(s) you will ask to try out your version of Gus
    • what user documentation or help will be necessary for them to use the application -- is it really, really self explanatory? Add online documentation and/or manuals to the task list for any use cases that would not be self-evident to any computer-literate grandmother.

    lecture 27 starts here

    Product Support

    Support for Using the Software

    What kinds of support have you seen for folks who just need to use the software?











    A lot of this is really about how long will it take (how much it will cost) to solve a problem. Humans timeout quickly, some more than others. If you give them the tools to fix the problem themselves, working on it immediately, they will probably be happier than if you make them wait for your fix.
    printed and online (noninteractive) manuals
    Manuals are out of style, but that is because as Negroponte would say, they are made out of atoms. The need for a good manual is very strong, proportional to the feature count of the software system.
    interactive tutorials
    Some of you criticized emacs' usability earlier this semester, but that's because your personal learning style didn't fit emacs' extensive online tutorial, or you never used the tutorial. Besides emacs, I learned UNIX shell programming, C programming, and EverQuest with the help of extensive interactive tutorials. The best tutorials test whether the material has been mastered, and report results or even adjust their content or exercises based on observed performance. Our semester project has, in places, interactive tutorial elements, but perhaps in order to get on the same page I should have forced all of us to go through some tutorials to get a feel for a variety of features in them.
    searchable help
    Besides being a hypertext form of the online manual, a help system usually has a search capability. Google is thus the world's largest help system, and if you get your manual searchable via google, you almost don't need to provide redundant internal capability. Almost.
    context sensitive help
    One area where google can't fulfill all your product support needs (yet) is in understanding the context of the question. To provide context to google one generally supplies additional keywords, but it doesn't really know which keywords are the search term and which are the context, it just searches for places where all the keywords show up in proximity.
    web or e-mail support
    we probably have all seen web forms that turn around and send an e-mail to the produt support team. One advantage of this method is that the team gets an electronic artifact that records the incident. A major deficiency of this method is, the user doesn't know (or may not feel) that they have been heard, and doesn't get an immediate answer. Sending an autoreply message let's them know that the system heard them, but doesn't guarantee a human will ever see their message, or care about them.
    online chat
    humans crave interactivity. if a user knows a human saw their plea for help they probably immediately will feel more hopeful and perhaps more emotionally prepared for whatever wait is needed.
    phone support
    the 45 minute wait on muzak might be tolerable if the phone support is good, but it is easy for this to go wrong.

    Fixing Problems that Occur

    How do you know a bug...is a bug?

    Bug Trackers

    Some past class projects have used Trac.

    There are plenty of fancy commercial Bug Trackers. There are popular open source ones. Check out this comparison chart of bug trackers.

    Personnel Issues

    From Bruegge Ch. 14:
    skill types
    application domain, communications, technical, quality, management
    skill matrix
    document staff primary skills, secondary skills, and interests; try to match up project needs with staff abilities.
    Tasks \ Participant Bill Mary SueEd
    control design 1,3 3
    databases 3 3 1
    UI 2 1,3
    config mgt 2 3
    role types
    management roles vs. technical roles
    cathedral model
    dictatorship from the top, control
    bazaar model
    chaos, peers, bottom-up

    Dr. J's observations regarding personnel issues

    Static Checking, revisited

    Extended Static Checker for Java: a local class copy installed at http://www2.cs.uidaho.edu/~jeffery/courses/384/escjava, but it is rhetorical for non-Java project years. There is a copy of the whole thing as a .tar.gz file in case you have trouble downloading from Ireland. My .bashrc for CS lab machines had to have a couple things added:

    export PATH=/home/jeffery/html/courses/384/escjava:$PATH
    export ESCTOOLS_RELEASE=/home/jeffery/html/courses/384/escjava
    export SIMPLIFY=Simplify-1.5.4.linux
    
    The same distribution, which tries to bundle a half-dozen platforms, almost (and sort-of) works for me on Windows, but may be somewhat sensitive about Java versions and such. It gives seemingly-bogus messages about class libraries (on my Windows box) and doesn't handle Java 1.5 stuff (in particular, Generics such as Comparator<tile>). There is at least one system (KIV) that claims to handle generics, but I haven't evaluated it yet.

    lecture 29 starts here

    In addition to your own prioritized task assignments, by the next sprint:

    lecture 30 starts here

    Risk Management

    (Bruegge pp. 607-609)

    best to do at the front of a proposed project, before you even commit to doing it
    risks entailed by not doing it are part of the calculation!
    in avionics certification, we saw software components be categorized as to the real-world risk
    A=catastrophic...E=no effect
    Risk Management is not just about the risk of component failure
    it is the risks during the software development process and whole software lifecycle.

    How to Do Risk Management

    identify potential problems
    Setup "information flows" such that risks and problems get reported. Developers often know the risks, but may not want to report them. Management can't manage what it isn't aware of. So what to do? Reward risk reporters? Make risk management activities obviously and directly beneficial to developers. You can also look for "the usual suspects", and come up with a lot of automatic and universal risks.
    analyze the risks
    there are several things to do by way of analysis of risks:
    risk categorizations There are many ways to categorize risks
    managerial risks and technical risks.
    Examples
    risk type
    COTS component doesn't work technical
    COTS component doesn't show up when needed managerial
    users hate/reject the user interface technical
    middlware too slow to meet perf. requirement technical
    development of subsystems takes longer than scheduled managerial
    generic risks versus product-specific risks
    Pressman says product-specific risks cause the most headaches, so pay extra attention to them.
    performance risk, cost risk, support risk, schedule risk
    This kind of categorization may help direct the risk management to the right person(s) for the job
    prioritize
    There are two dimensions: probability P of a risk occurring and impact I of what negative effect the risk may have. These are categorizations that drive urgency of attention or value of resources to assign to the risk. Impact I might be the same or similar to the A-E scale we saw for avionics.
    address the risks in a timely fashion
    can this risk be avoided entirely? can its P or its I be reduced?
    risk type P I mitigation
    COTS component doesn't work technical 0.1 0.9
    • test for full function
    • write around glitches
    COTS component doesn't show up when needed managerial 0.3 0.8
    • order early
    • pester supply chain
    users hate/reject the user interface technical 0.6 1.0
    • usability studies
    • rewrite interface
    middleware too slow to meet perf. requirement technical 0.2 0.9
    • performance evaluation as part of selection criteria
    development of subsystems takes longer than scheduled managerial 0.8 0.9
    • increase task priority
    • assign key developers
    One thing understated in some textbook descriptions of risk management is that risk mitigation allocations compete with each other and with core development resources. Some viable mitigation options may not be worth it.

    Capability Maturity Model (CMM and CMMI)

    (Bruegge section 15.3)

    Consider the CMM levels 1-5, given below. Which ones are recognizable?
    Level 1: Initial ad hoc; depends entirely on personnel; unmanaged
    Level 2: Repeatable projects use life-cycle models; basic management; client reviews and acceptance tests
    Level 3: Defined documents all managerial and technical activities across life cycle
    Level 4: Managed metrics for activities and deliverables. data collection throughout project. client knows about risks and measures used for project.
    Level 5: Optimized measurements are used to improve the model during the project
    On May 2 and 4 you will each summarize in 5-10 minutes your particular contribution to your team's project. The final will be 12:30-2:30pm on XXXday May 10? Double-check.

    lecture 31 starts here

    lecture 32 starts here

    Release Day

    Part of your team's grade, not just individuals assigned to the task, will be based on how your team did on testing, including what kinds and how much testing can be documented. "Documented" includes: showing results of test runs, bugs found (and possibly subsequently fixed), scripts that allow as much as possible of the tests to be rerun automatically (for example, invoking JUnit or similar), and or manual how-to-run-"test X" instructions.

    You can think of it thus: the milestone checklist primarily identifies what has been implemented but says nothing about whether it was implemented well. Testing still doesn't prove correctness or quality, but it is necessary to have any hope of approaching those goals.

    lecture 33 starts here

    Profiling

    A profiler is an execution monitor which measures the number of executions or amount of time spent executing the different parts of a program's code. Profiling is motivated by the old 80-20 rule: if 80% of execution time is spent in 20% of the code, then by identifying that 20% of the code we can focus our attention on improving its correctness and performance.

    Who Uses Profilers?

    Application developers use profilers largely for performance tuning. System platform providers use profilers to tune kernels, compiler runtime systems, and libraries. As an undergrad I wrote a profiler (for C) which was used to provide input for a code generator which would dynamically improve its generated code based on application runs.

    Kinds of Profiling

    counting
    a profile can report how many times something executed. Precise. Potentially expensive.
    timing
    a profile can report semi-exact times spent in each program unit, but it is very expensive to do so!
    statistical sampling
    many profilers such as gprof check the program counter register every clock tick to approximate the amount of time spent in each unit
    Profiling is somewhat related to test coverage; telling you what code has not been executed is the same as telling you a profile count of 0.

    Profiler Granularity

    Profilers vary in granularity; source-code granularities often range from function-level, statement-level and expression-level. It is tempting to work at the basic block level, since all instructions in a basic block will execute the same number of times. Q: does basic block granularity correspond to statement-level, or expression-level?

    Java Profilers

    The only Java profiler I have used was JProbe, a commercial tool which has been around awhile and worked pretty well for me on a project at the National Library of Medicine. JProbe puts out pretty output like this:

    This is an app dominated by its PNG-writer.

    Profiling Example

    As another profiling example, let's look at the Unicon virtual machine and see where it spends its time. The Unicon virtual machine, named iconx, is in many ways a typical giant C program. To profile it, I had to compile and link with -pg as well as -g options, and then disable its internal use of the UNIX profil(2) interface! One difference between iconx and some C programs is that its inputs vary more widely than is normal: different programs may use very different language features and spend their time in different places in the virtual machine and its runtime system. We will look at its profile when executing one particular program which is by definition "representative" since it was sent to us by a user in Croatia.

    Analysis: this result suggests 2/3rds of execution time on this application is spent in interp_0, the virtual machine interpreter's main loop. A lot of time is also spent derefencing (this is the act of following a memory reference (pointer) to obtain its value), and in type checking and conversion functions. The program garbage collected 25 times, but apparently without spending any significant time at it ?! Statistical approximation has its pros and cons.

    Flat profile:
    
    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls  ms/call  ms/call  name    
     65.13     25.09    25.09  9876086     0.00     0.00  interp_0
      6.63     27.64     2.56 108318639     0.00     0.00  deref_0
      3.63     29.05     1.40  8472811     0.00     0.00  invoke
      2.93     30.18     1.13 61891780     0.00     0.00  cnv_ec_int
      2.39     31.09     0.92 28907412     0.00     0.00  Oasgn
      2.23     31.95     0.86 17074006     0.00     0.00  Oplus
      1.61     32.58     0.62 14237739     0.00     0.00  equiv
      1.30     33.08     0.50  1355071     0.00     0.00  Zfind
      1.22     33.55     0.47   634739     0.00     0.00  cstos
      1.14     33.98     0.44 12019549     0.00     0.00  Onumeq
      0.93     34.34     0.36 10561077     0.00     0.00  alcsubs_0
      0.92     34.70     0.35  3273189     0.00     0.00  Ofield
      0.88     35.04     0.34   862347     0.00     0.00  Obang
      0.71     35.31     0.28  1562097     0.00     0.00  alcstr_0
      0.66     35.57     0.26  6147174     0.00     0.00  lexcmp
      0.65     35.82     0.25       25    10.00    10.00  adjust
      0.60     36.05     0.23       25     9.20     9.20  compact
      0.57     36.27     0.22 14175397     0.00     0.00  Oeqv
      0.49     36.46     0.19  5398727     0.00     0.00  Olexeq
      0.45     36.63     0.17 17073415     0.00     0.00  add
      0.43     36.80     0.17  5214968     0.00     0.00  cvpos
      0.39     36.95     0.15  4091331     0.00     0.00  Osize
      0.38     37.09     0.14  1405720     0.00     0.00  Osubsc
      0.36     37.23     0.14  5542081     0.00     0.00  cnv_c_int
      0.35     37.37     0.14  1715559     0.00     0.00  Osect
      0.29     37.48     0.11   459321     0.00     0.00  Ztab
      0.23     37.57     0.09  6579734     0.00     0.00  cnv_tstr_0
      0.19     37.65     0.07                             deref_1
      0.18     37.72     0.07     3277     0.02     0.02  cnv_eint
      0.16     37.77     0.06  1005214     0.00     0.00  alcrecd_0
      0.14     37.83     0.06  4179269     0.00     0.00  cnv_str_0
      0.13     37.88     0.05  1088962     0.00     0.00  Olexne
      0.13     37.93     0.05   870748     0.00     0.00  Ocater
      0.13     37.98     0.05                             Olexlt
      0.12     38.02     0.04  2186145     0.00     0.00  Oneg
      0.12     38.07     0.04  1005214     0.00     0.00  Omkrec
      0.10     38.11     0.04   482109     0.00     0.00  retderef
      0.10     38.15     0.04                             Oneqv
      0.10     38.19     0.04                             cnv_tstr_1
      0.08     38.22     0.03   341945     0.00     0.00  Onumlt
      0.08     38.25     0.03                             alcsubs_1
      0.05     38.27     0.02   634739     0.00     0.00  Kletters
      0.05     38.29     0.02   184281     0.00     0.00  Obscan
      0.05     38.31     0.02    58899     0.00     0.00  sub
      0.04     38.33     0.01                             Orefresh
      0.03     38.34     0.01   274449     0.00     0.00  Zmove
      0.03     38.34     0.01   114371     0.00     0.00  memb
      0.03     38.35     0.01    98987     0.00     0.00  Ollist
      0.03     38.37     0.01    90644     0.00     0.00  itos
      0.03     38.38     0.01    85123     0.00     0.00  Onull
      0.03     38.38     0.01    58210     0.00     0.00  Onumge
      0.03     38.40     0.01    27206     0.00     0.00  tvtbl_asgn
      0.03     38.41     0.01    25048     0.00     0.00  Otoby
      0.03     38.41     0.01    15488     0.00     0.00  hmake
      0.03     38.42     0.01       26     0.38     0.41  Opowr
      0.03     38.44     0.01                             Orandom
      0.03     38.45     0.01                             cnv_cset_1
      0.03     38.45     0.01                             rtos
      0.01     38.46     0.01  2186145     0.00     0.00  neg
      0.01     38.47     0.01   454303     0.00     0.00  pollevent
      0.01     38.47     0.01    81191     0.00     0.00  alctvtbl_0
      0.01     38.48     0.01     3876     0.00     0.00  div3
      0.01     38.48     0.01        1     5.00     5.00  ston
      0.01     38.48     0.01                             Onumber
      0.01     38.49     0.01                             Otabmat
      0.01     38.49     0.01                             alcselem_1
      0.01     38.50     0.01                             alctelem_1
      0.01     38.51     0.01                             cnv_real_1
      0.01     38.51     0.01                             handle_misc
      0.01     38.52     0.01                             order
      0.01     38.52     0.01                             printable
    
    [... many additional functions omitted with 0.00 times ...]
    
     %         the percentage of the total running time of the
    time       program used by this function.
    
    cumulative a running sum of the number of seconds accounted
     seconds   for by this function and those listed above it.
    
     self      the number of seconds accounted for by this
    seconds    function alone.  This is the major sort for this
               listing.
    
    calls      the number of times this function was invoked, if
               this function is profiled, else blank.
     
     self      the average number of milliseconds spent in this
    ms/call    function per call, if this function is profiled,
    	   else blank.
    
     total     the average number of milliseconds spent in this
    ms/call    function and its descendents per call, if this 
    	   function is profiled, else blank.
    
    name       the name of the function.  This is the minor sort
               for this listing. The index shows the location of
    	   the function in the gprof listing. If the index is
    	   in parenthesis it shows where it would appear in
    	   the gprof listing if it were to be printed.
    
    		     Call graph (explanation follows)
    
    
    granularity: each sample hit covers 4 byte(s) for 0.03% of 38.52 seconds
    
    index % time    self  children    called     name
                                                     
    [1]     99.2    0.00   38.20                 main [1]
                   26.08   12.12       1/1           interp_0  [3]
                    0.00    0.00       1/1           icon_init [108]
                    0.00    0.00       1/1           icon_setup [162]
                    0.00    0.00       1/1           c_exit [157]
    -----------------------------------------------
    [2]     99.2   26.08   12.12       1+13037195  [2]
                   25.09   11.25 9876086             interp_0  [3]
                    0.50    0.34 1355071             Zfind  [10]
                    0.11    0.03  459321             Ztab  [35]
                    0.02    0.03  184281             Obscan  [45]
                    0.01    0.01  274449             Zmove  [58]
                    0.01    0.00   25048             Otoby  [64]
                    0.00    0.00       2             Kdateline  [112]
                    0.00    0.00     591             Oescan  [135]
    -----------------------------------------------
                                       2             Kdateline  [112]
                                     591             Oescan  [135]
                                  184281             Obscan  [45]
                                  254212             Otoby  [64]
                                  274449             Zmove  [58]
                                  459321             Ztab  [35]
                                  721346             Zfind  [10]
                                 7981883             Obang  [12]
                   26.08   12.12       1/1           main [1]
    [3]     94.3   25.09   11.25 9876086         interp_0  [3]
                    1.40    0.51 8472811/8472811     invoke [5]
                    0.86    0.81 17074006/17074006     Oplus [6]
                    1.45    0.01 61341591/108318639     deref_0 [4]
                    0.92    0.22 28907412/28907412     Oasgn [7]
                    0.44    0.44 12019549/12019549     Onumeq [9]
                    0.22    0.62 14175397/14175397     Oeqv [11]
                    0.19    0.31 5398727/5398727     Olexeq [15]
                    0.05    0.41  870748/870748      Ocater [20]
                    0.14    0.32 1715559/1715559     Osect [21]
                    0.35    0.08 3273189/3273189     Ofield [22]
                    0.01    0.40   97223/98987       Ollist [23]
                    0.14    0.18 1405720/1405720     Osubsc [26]
                    0.15    0.00 4091331/4091331     Osize [33]
                    0.05    0.06 1088962/1088962     Olexne [36]
                    0.04    0.06 1005214/1005214     Omkrec [37]
                    0.04    0.05 2186145/2186145     Oneg [39]
                    0.00    0.07   15487/15487       Ztable [42]
                    0.04    0.01  482109/482109      retderef [46]
                    0.03    0.02  341945/341945      Onumlt [48]
                    0.00    0.03    4466/4466        Odivide [51]
                    0.01    0.01   58210/58210       Onumge [53]
                    0.00    0.02   58899/58899       Ominus [54]
                    0.02    0.00  634739/634739      Kletters [55]
                    0.00    0.01    9755/9755        Omult [61]
                    0.01    0.00   85123/85123       Onull [63]
                    0.01    0.00      26/26          Opowr [65]
                    0.00    0.01  221203/221203      Onumle [72]
                    0.01    0.00  454303/454303      pollevent [74]
                    0.00    0.00  145157/145157      Ononnull [86]
                    0.00    0.00     588/588         Olconcat [87]
                    0.00    0.00   39852/39852       Onumgt [90]
                    0.00    0.00   27013/27013       Zchar [91]
                    0.00    0.00    5686/5686        Zmember [92]
                    0.00    0.00    8996/8996        Oswap [93]
                    0.00    0.00     594/594         Zrepl [94]
                    0.00    0.00     294/294         Zmap [96]
                    0.00    0.00     591/591         Zstring [97]
                    0.00    0.00    1230/1230        Zwrite [98]
                    0.00    0.00     591/591         Zwrites [99]
                    0.00    0.00     481/481         Zinsert [100]
                    0.00    0.00    1764/1764        Zget [101]
                    0.00    0.00     903/903         Onumne [102]
                    0.00    0.00       5/5           Zlist [103]
                    0.00    0.00       3/3           Zread [104]
                    0.00    0.00       1/1           Zset [110]
                    0.00    0.00       8/8           Zright [111]
                    0.00    0.00  127352/127352      Zput [114]
                    0.00    0.00    2346/2346        Ktime [129]
                    0.00    0.00    1181/1181        Zreal [132]
                    0.00    0.00    1171/1171        Zpull [134]
                    0.00    0.00     591/591         Zinteger [136]
                                 1355071             Zfind  [10]
                                  862347             Obang  [12]
                                  459321             Ztab  [35]
                                  274449             Zmove  [58]
                                  184281             Obscan  [45]
                                   25048             Otoby  [64]
                                     591             Oescan  [135]
                                       2             Kdateline  [112]
    -----------------------------------------------
                                 18831966             deref_0 [4]
                    0.00    0.00   17992/108318639     Oswap [93]
                    0.00    0.00   40499/108318639     subs_asgn [71]
                    0.00    0.00   85123/108318639     Onull [63]
                    0.00    0.00  145157/108318639     Ononnull [86]
                    0.00    0.00  184281/108318639     Obscan  [45]
                    0.01    0.00  482109/108318639     retderef [46]
                    0.06    0.00 2583420/108318639     Osect [21]
                    0.06    0.00 2715935/108318639     Osubsc [26]
                    0.08    0.00 3265455/108318639     Ofield [22]
                    0.19    0.00 7978330/108318639     Obang  [12]
                    0.20    0.00 8297681/108318639     Oasgn [7]
                    0.50    0.00 21181066/108318639     invoke [5]
                    1.45    0.01 61341591/108318639     interp_0  [3]
    [4]      6.7    2.55    0.01 108318639+18831966 deref_0 [4]
                    0.01    0.00   80998/114371      memb [62]
                                 18831966             deref_0 [4]
    -----------------------------------------------
                    1.40    0.51 8472811/8472811     interp_0  [3]
    [5]      5.0    1.40    0.51 8472811         invoke [5]
                    0.50    0.00 21181066/108318639     deref_0 [4]
                    0.00    0.01    1764/98987       Ollist [23]
    -----------------------------------------------
                    0.86    0.81 17074006/17074006     interp_0  [3]
    [6]      4.3    0.86    0.81 17074006         Oplus [6]
                    0.62    0.00 34147421/61891780     cnv_ec_int [8]
                    0.17    0.00 17073415/17073415     add [31]
                    0.01    0.00     591/3277        cnv_eint [43]
                    0.00    0.00    1182/6521        cnv_c_dbl [126]
                    0.00    0.00     591/3589        alcreal_0 [128]
    -----------------------------------------------
                    0.92    0.22 28907412/28907412     interp_0  [3]
    [7]      3.0    0.92    0.22 28907412         Oasgn [7]
                    0.20    0.00 8297681/108318639     deref_0 [4]
                    0.01    0.00   27206/27206       tvtbl_asgn [60]
                    0.00    0.01   40499/40499       subs_asgn [71]
    -----------------------------------------------
                    0.00    0.00      26/61891780     Opowr [65]
                    0.00    0.00    1806/61891780     Onumne [102]
                    0.00    0.00    8932/61891780     Odivide [51]
                    0.00    0.00   18919/61891780     Omult [61]
                    0.00    0.00   50096/61891780     Otoby  [64]
                    0.00    0.00   79704/61891780     Onumgt [90]
                    0.00    0.00  115829/61891780     Onumge [53]
                    0.00    0.00  117798/61891780     Ominus [54]
                    0.01    0.00  442406/61891780     Onumle [72]
                    0.01    0.00  683600/61891780     Onumlt [48]
                    0.04    0.00 2186145/61891780     Oneg [39]
                    0.44    0.00 24039098/61891780     Onumeq [9]
                    0.62    0.00 34147421/61891780     Oplus [6]
    [8]      2.9    1.13    0.01 61891780         cnv_ec_int [8]
                    0.01    0.00       1/1           ston [77]
    -----------------------------------------------
                    0.44    0.44 12019549/12019549     interp_0  [3]
    [9]      2.3    0.44    0.44 12019549         Onumeq [9]
                    0.44    0.00 24039098/61891780     cnv_ec_int [8]
    -----------------------------------------------
                                 1355071             interp_0  [3]
    [10]     2.2    0.50    0.34 1355071         Zfind  [10]
                    0.03    0.31 2252003/4179269     cnv_str_0 [13]
                                  721346             interp_0  [3]
    -----------------------------------------------
                    0.22    0.62 14175397/14175397     interp_0  [3]
    [11]     2.2    0.22    0.62 14175397         Oeqv [11]
                    0.62    0.00 14175397/14237739     equiv [14]
    -----------------------------------------------
                                  862347             interp_0  [3]
    [12]     2.1    0.34    0.46  862347         Obang  [12]
                    0.27    0.00 7940505/10561077     alcsubs_0 [25]
                    0.19    0.00 7978330/108318639     deref_0 [4]
                                 7981883             interp_0  [3]
    -----------------------------------------------
                    0.00    0.00       8/4179269     Zright [111]
                    0.00    0.00     296/4179269     Zmap [96]
                    0.00    0.00     591/4179269     Zstring [97]
                    0.00    0.00     594/4179269     Zrepl [94]
                    0.00    0.03  184281/4179269     Obscan  [45]
                    0.02    0.24 1741496/4179269     Ocater [20]
                    0.03    0.31 2252003/4179269     Zfind  [10]
    [13]     1.7    0.06    0.58 4179269         cnv_str_0 [13]
                    0.47    0.00  634739/634739      cstos [19]
                    0.11    0.00  636485/1562097     alcstr_0 [27]
                    0.00    0.00    1746/90644       itos [66]
    -----------------------------------------------
                    0.00    0.00   62342/14237739     memb [62]
                    0.62    0.00 14175397/14237739     Oeqv [11]
    [14]     1.6    0.62    0.00 14237739         equiv [14]
    -----------------------------------------------
                    0.19    0.31 5398727/5398727     interp_0  [3]
    [15]     1.3    0.19    0.31 5398727         Olexeq [15]
                    0.22    0.00 5392265/6147174     lexcmp [28]
                    0.07    0.01 5398727/6579734     cnv_tstr_0 [38]
    -----------------------------------------------
                    0.00    0.00       3/115683      Zread [104]
                    0.00    0.00       6/115683      alcrecd_0 [44]
                    0.00    0.00      18/115683      alcsubs_0 [25]
                    0.00    0.00     588/115683      alclist_0 [88]
                    0.00    0.06   15488/115683      hmake [41]
                    0.00    0.41   99580/115683      alclist_raw_0 [24]
    [16]     1.2    0.00    0.48  115683         reserve_0 [16]
                    0.00    0.48      25/25          collect [17]
                    0.00    0.00      25/25          findgap [144]
    -----------------------------------------------
                    0.00    0.48      25/25          reserve_0 [16]
    [17]     1.2    0.00    0.48      25         collect [17]
                    0.00    0.48      25/25          reclaim [18]
                    0.00    0.00      50/1700        markblock  [122]
                    0.00    0.00      50/25485       postqual [118]
                    0.00    0.00      25/25          markprogram [145]
                    0.00    0.00      25/25          mmrefresh [146]
    -----------------------------------------------
                    0.00    0.48      25/25          collect [17]
    [18]     1.2    0.00    0.48      25         reclaim [18]
                    0.25    0.00      25/25          adjust [29]
                    0.23    0.00      25/25          compact [30]
                    0.00    0.00      25/25          cofree [143]
                    0.00    0.00      25/25          scollect [147]
    -----------------------------------------------
                    0.47    0.00  634739/634739      cnv_str_0 [13]
    [19]     1.2    0.47    0.00  634739         cstos [19]
    -----------------------------------------------
                    0.05    0.41  870748/870748      interp_0  [3]
    [20]     1.2    0.05    0.41  870748         Ocater [20]
                    0.02    0.24 1741496/4179269     cnv_str_0 [13]
                    0.15    0.00  841141/1562097     alcstr_0 [27]
    -----------------------------------------------
                    0.14    0.32 1715559/1715559     interp_0  [3]
    [21]     1.2    0.14    0.32 1715559         Osect [21]
                    0.11    0.00 3431118/5214968     cvpos [32]
                    0.09    0.00 3431118/5542081     cnv_c_int [34]
                    0.06    0.00 2583420/108318639     deref_0 [4]
                    0.06    0.00 1714971/10561077     alcsubs_0 [25]
                    0.00    0.00     588/588         cplist_0 [89]
    -----------------------------------------------
                    0.35    0.08 3273189/3273189     interp_0  [3]
    [22]     1.1    0.35    0.08 3273189         Ofield [22]
                    0.08    0.00 3265455/108318639     deref_0 [4]
    -----------------------------------------------
                    0.00    0.01    1764/98987       invoke [5]
                    0.01    0.40   97223/98987       interp_0  [3]
    [23]     1.1    0.01    0.41   98987         Ollist [23]
                    0.00    0.41   98987/99580       alclist_raw_0 [24]
    -----------------------------------------------
                    0.00    0.00       5/99580       Zlist [103]
                    0.00    0.00     588/99580       Olconcat [87]
                    0.00    0.41   98987/99580       Ollist [23]
    [24]     1.1    0.00    0.41   99580         alclist_raw_0 [24]
                    0.00    0.41   99580/115683      reserve_0 [16]
    -----------------------------------------------
                    0.03    0.00  905601/10561077     Osubsc [26]
                    0.06    0.00 1714971/10561077     Osect [21]
                    0.27    0.00 7940505/10561077     Obang  [12]
    [25]     0.9    0.36    0.00 10561077         alcsubs_0 [25]
                    0.00    0.00      18/115683      reserve_0 [16]
    -----------------------------------------------
                    0.14    0.18 1405720/1405720     interp_0  [3]
    [26]     0.8    0.14    0.18 1405720         Osubsc [26]
                    0.06    0.00 2715935/108318639     deref_0 [4]
                    0.04    0.00 1324529/5214968     cvpos [32]
                    0.03    0.00 1324529/5542081     cnv_c_int [34]
                    0.03    0.00  905601/10561077     alcsubs_0 [25]
                    0.01    0.00   81191/81191       alctvtbl_0 [75]
                    0.00    0.00   81191/87358       hash [116]
    -----------------------------------------------
                    0.00    0.00       2/1562097     Kdateline  [112]
                    0.00    0.00       3/1562097     Zread [104]
                    0.00    0.00       8/1562097     Zright [111]
                    0.00    0.00     294/1562097     Zmap [96]
                    0.00    0.00     594/1562097     Zrepl [94]
                    0.01    0.00   40499/1562097     subs_asgn [71]
                    0.01    0.00   43071/1562097     Olexne [36]
                    0.11    0.00  636485/1562097     cnv_str_0 [13]
                    0.15    0.00  841141/1562097     Ocater [20]
    [27]     0.7    0.28    0.00 1562097         alcstr_0 [27]
    -----------------------------------------------
                    0.00    0.00     141/6147174     dp_pnmcmp [105]
                    0.03    0.00  754768/6147174     Olexne [36]
                    0.22    0.00 5392265/6147174     Olexeq [15]
    [28]     0.7    0.26    0.00 6147174         lexcmp [28]
    -----------------------------------------------
                    0.25    0.00      25/25          reclaim [18]
    [29]     0.6    0.25    0.00      25         adjust [29]
    -----------------------------------------------
                    0.23    0.00      25/25          reclaim [18]
    [30]     0.6    0.23    0.00      25         compact [30]
                    0.00    0.00   13587/13587       mvc [123]
    -----------------------------------------------
                    0.17    0.00 17073415/17073415     Oplus [6]
    [31]     0.5    0.17    0.00 17073415         add [31]
    -----------------------------------------------
                    0.01    0.00  459321/5214968     Ztab  [35]
                    0.04    0.00 1324529/5214968     Osubsc [26]
                    0.11    0.00 3431118/5214968     Osect [21]
    [32]     0.4    0.17    0.00 5214968         cvpos [32]
    -----------------------------------------------
                    0.15    0.00 4091331/4091331     interp_0  [3]
    [33]     0.4    0.15    0.00 4091331         Osize [33]
    -----------------------------------------------
                    0.00    0.00     594/5542081     Zrepl [94]
                    0.00    0.00   25048/5542081     Otoby  [64]
                    0.00    0.00   27013/5542081     Zchar [91]
                    0.02    0.00  733779/5542081     def_c_int [57]
                    0.03    0.00 1324529/5542081     Osubsc [26]
                    0.09    0.00 3431118/5542081     Osect [21]
    [34]     0.4    0.14    0.00 5542081         cnv_c_int [34]
    -----------------------------------------------
                                  459321             interp_0  [3]
    [35]     0.4    0.11    0.03  459321         Ztab  [35]
                    0.01    0.00  459321/5214968     cvpos [32]
                    0.00    0.01  459321/735547      def_c_int [57]
                                  459321             interp_0  [3]
    -----------------------------------------------
                    0.05    0.06 1088962/1088962     interp_0  [3]
    [36]     0.3    0.05    0.06 1088962         Olexne [36]
                    0.03    0.00  754768/6147174     lexcmp [28]
                    0.02    0.00 1132327/6579734     cnv_tstr_0 [38]
                    0.01    0.00   43071/1562097     alcstr_0 [27]
    -----------------------------------------------
                    0.04    0.06 1005214/1005214     interp_0  [3]
    [37]     0.3    0.04    0.06 1005214         Omkrec [37]
                    0.06    0.00 1005214/1005214     alcrecd_0 [44]
    -----------------------------------------------
                    0.00    0.00    8181/6579734     def_tstr [95]
                    0.00    0.00   40499/6579734     subs_asgn [71]
                    0.02    0.00 1132327/6579734     Olexne [36]
                    0.07    0.01 5398727/6579734     Olexeq [15]
    [38]     0.3    0.09    0.01 6579734         cnv_tstr_0 [38]
                    0.00    0.01   88898/88898       tmp_str [70]
    -----------------------------------------------
                    0.04    0.05 2186145/2186145     interp_0  [3]
    [39]     0.2    0.04    0.05 2186145         Oneg [39]
                    0.04    0.00 2186145/61891780     cnv_ec_int [8]
                    0.01    0.00 2186145/2186145     neg [73]
    -----------------------------------------------
                                                     
    [40]     0.2    0.07    0.00                 deref_1 [40]
    -----------------------------------------------
                    0.00    0.00       1/15488       Zset [110]
                    0.01    0.06   15487/15488       Ztable [42]
    [41]     0.2    0.01    0.06   15488         hmake [41]
                    0.00    0.06   15488/115683      reserve_0 [16]
                    0.00    0.00   15488/15488       alchash_0 [121]
                    0.00    0.00   15488/15494       alcsegment_0 [120]
    -----------------------------------------------
                    0.00    0.07   15487/15487       interp_0  [3]
    [42]     0.2    0.00    0.07   15487         Ztable [42]
                    0.01    0.06   15487/15488       hmake [41]
    -----------------------------------------------
                    0.00    0.00      26/3277        Opowr [65]
                    0.01    0.00     298/3277        Onumlt [48]
                    0.01    0.00     591/3277        Omult [61]
                    0.01    0.00     591/3277        Oplus [6]
                    0.01    0.00     591/3277        Onumge [53]
                    0.03    0.00    1180/3277        Odivide [51]
    [43]     0.2    0.07    0.00    3277         cnv_eint [43]
    -----------------------------------------------
                    0.06    0.00 1005214/1005214     Omkrec [37]
    [44]     0.2    0.06    0.00 1005214         alcrecd_0 [44]
                    0.00    0.00       6/115683      reserve_0 [16]
    -----------------------------------------------
                                  184281             interp_0  [3]
    [45]     0.1    0.02    0.03  184281         Obscan  [45]
                    0.00    0.03  184281/4179269     cnv_str_0 [13]
                    0.00    0.00  184281/108318639     deref_0 [4]
                                  184281             interp_0  [3]
    -----------------------------------------------
                    0.04    0.01  482109/482109      interp_0  [3]
    [46]     0.1    0.04    0.01  482109         retderef [46]
                    0.01    0.00  482109/108318639     deref_0 [4]
    -----------------------------------------------
                                                     
    [47]     0.1    0.05    0.00                 Olexlt [47]
    -----------------------------------------------
                    0.03    0.02  341945/341945      interp_0  [3]
    [48]     0.1    0.03    0.02  341945         Onumlt [48]
                    0.01    0.00  683600/61891780     cnv_ec_int [8]
                    0.01    0.00     298/3277        cnv_eint [43]
                    0.00    0.00     588/6521        cnv_c_dbl [126]
                    0.00    0.00      19/3589        alcreal_0 [128]
    -----------------------------------------------
                                                     
    [49]     0.1    0.04    0.00                 Oneqv [49]
    -----------------------------------------------
                                                     
    [50]     0.1    0.04    0.00                 cnv_tstr_1 [50]
    -----------------------------------------------
                    0.00    0.03    4466/4466        interp_0  [3]
    [51]     0.1    0.00    0.03    4466         Odivide [51]
                    0.03    0.00    1180/3277        cnv_eint [43]
                    0.01    0.00    3876/3876        div3 [76]
                    0.00    0.00    8932/61891780     cnv_ec_int [8]
                    0.00    0.00    1180/6521        cnv_c_dbl [126]
                    0.00    0.00     590/3589        alcreal_0 [128]
    -----------------------------------------------
                                                     
    [52]     0.1    0.03    0.00                 alcsubs_1 [52]
    -----------------------------------------------
                    0.01    0.01   58210/58210       interp_0  [3]
    [53]     0.1    0.01    0.01   58210         Onumge [53]
                    0.01    0.00     591/3277        cnv_eint [43]
                    0.00    0.00  115829/61891780     cnv_ec_int [8]
                    0.00    0.00    1182/6521        cnv_c_dbl [126]
                    0.00    0.00     591/3589        alcreal_0 [128]
    -----------------------------------------------
                    0.00    0.02   58899/58899       interp_0  [3]
    [54]     0.1    0.00    0.02   58899         Ominus [54]
                    0.02    0.00   58899/58899       sub [56]
                    0.00    0.00  117798/61891780     cnv_ec_int [8]
    -----------------------------------------------
                    0.02    0.00  634739/634739      interp_0  [3]
    [55]     0.1    0.02    0.00  634739         Kletters [55]
    -----------------------------------------------
                    0.02    0.00   58899/58899       Ominus [54]
    [56]     0.1    0.02    0.00   58899         sub [56]
    -----------------------------------------------
    [57-166] omitted by Dr. J for lack of interest in their 0.0 values
    -----------------------------------------------
    
     This table describes the call tree of the program, and was sorted by
     the total amount of time spent in each function and its children.
    
     Each entry in this table consists of several lines.  The line with the
     index number at the left hand margin lists the current function.
     The lines above it list the functions that called this function,
     and the lines below it list the functions this one called.
     This line lists:
         index	A unique number given to each element of the table.
    		Index numbers are sorted numerically.
    		The index number is printed next to every function name so
    		it is easier to look up where the function in the table.
    
         % time	This is the percentage of the `total' time that was spent
    		in this function and its children.  Note that due to
    		different viewpoints, functions excluded by options, etc,
    		these numbers will NOT add up to 100%.
    
         self	This is the total amount of time spent in this function.
    
         children	This is the total amount of time propagated into this
    		function by its children.
    
         called	This is the number of times the function was called.
    		If the function called itself recursively, the number
    		only includes non-recursive calls, and is followed by
    		a `+' and the number of recursive calls.
    
         name	The name of the current function.  The index number is
    		printed after it.  If the function is a member of a
    		cycle, the cycle number is printed between the
    		function's name and the index number.
    
    
     For the function's parents, the fields have the following meanings:
    
         self	This is the amount of time that was propagated directly
    		from the function into this parent.
    
         children	This is the amount of time that was propagated from
    		the function's children into this parent.
    
         called	This is the number of times this parent called the
    		function `/' the total number of times the function
    		was called.  Recursive calls to the function are not
    		included in the number after the `/'.
    
         name	This is the name of the parent.  The parent's index
    		number is printed after it.  If the parent is a
    		member of a cycle, the cycle number is printed between
    		the name and the index number.
    
     If the parents of the function cannot be determined, the word
     `' is printed in the `name' field, and all the other
     fields are blank.
    
     For the function's children, the fields have the following meanings:
    
         self	This is the amount of time that was propagated directly
    		from the child into the function.
    
         children	This is the amount of time that was propagated from the
    		child's children to the function.
    
         called	This is the number of times the function called
    		this child `/' the total number of times the child
    		was called.  Recursive calls by the child are not
    		listed in the number after the `/'.
    
         name	This is the name of the child.  The child's index
    		number is printed after it.  If the child is a
    		member of a cycle, the cycle number is printed
    		between the name and the index number.
    
     If there are any cycles (circles) in the call graph, there is an
     entry for the cycle-as-a-whole.  This entry shows who called the
     cycle (as parents) and the members of the cycle (as children.)
     The `+' recursive calls entry shows the number of function calls that
     were internal to the cycle, and the calls entry for each member shows,
     for that member, how many times it was called from other members of
     the cycle.
    

    Computer Supported Collaborative Work

    CSCW (sometimes called "groupware") is the field of using computers to assist in the communication and coordination tasks of multi-person projects.

    Basic questions:

    CSCW tools are sometimes related to CASE (Computer-Aided Software Engineering) tools. In general, CASE tools do not have to focus on group interaction, and CSCW tools include many types of work besides software engineering. A Venn diagram would probably show a giant CSCW circle with a modest overlap to a much smaller CASE circle.

    Pfeifer's Overview Pages

    Someone from Canada has a nice overview of CSCW on their website.

    CSCW Conferences

    There are two primary research conferences on CSCW, held in alternating years, one in North America (CSCW) and one in Europe (ECSCE). From recent conference papers CSCW can be inferred to span topics such as:

    E-mail, Chat, IM, newsgroups, WWW

    The original CSCW tool, e-mail, is still the heaviest use of the Internet. Many or most of the important CSCW ideas vastly predate the WWW.

    Is there any difference between "communication tool" and "computer supported cooperative work tool"?

    Notes*, Outlook, UW Calendar

    Lotus Notes, Domino, and related products comprise an "integrated collaborative environment", providing messaging, calendaring, scheduling, and an infrastructure for additional organization-specific applications. Providing a single point of access, security, and high-availability for these applications is a Good Thing.

    Microsoft Outlook is a ubiquitous scheduling tool for coordinating folks' calenders and setting up meetings.

    Many open source calendar applications are out there, but UW Calendar is probably important, because they are my alma mater, and because they seem to deliver major working tools (e.g. pine).

    SourceForge

  • A website providing free service to free software developers
  • A "collaborative software development platform" consisting of:
    collaborative development system web tools
    a web interface for project administration; group membership and permissions
    web server
    hosting documentation as well as source and binary distributions
    trackers for providing support
    bug tracking, patches, suggestion boxes
    mailing lists, discussion forums
    web-based administration, archival of messages, etc.
    shell service and compile farm
    a diverse network of hosts running many operating systems
    mysql
    for use with the website or the project itself
    CVS
    a repository for the source code
    vhost
    virtual hosting (but not DNS) for registered domains
    trove
    project listsings within a massive databse of open source projects

    Collaborative Editors

    How do n users edit the same document at the same time? How do they see each other's changes in real-time? How do they merge changes?
    • Option A (manual): make them all sit in a meeting room, let one person at a time serve as the typist for the group.
    • Option B (semi-realtime): use CVS, run cvs commit and cvs update a lot. Imagine a text editor in which cvs commit was a single-key operation, and cvs update was performed automatically once every few seconds...
    • Option C (asynchronous, passing the baton): Microsoft Word lets you turn on change tracking, and then each user's changes are color-coded for later review by others.
    • Option D (collaborative editor): file is shared by n users in realtime. Each user sees the others. Various architectures (central document, replicated document) and collaboration styles (separate cursors for each user; users sharing a cursor...).

    A collaborative editor example: ICI (part of CVE)

    In the following example, a person wishing to collaborate on a given piece of source code opens the file in question, clicks on the person that they want to collaborate with, and clicks "Invite User" (the GUI has changed a bit since this screenshot, but the idea is the same).

    On the receiving end, the person sees a popup window informing them of the invitation, which they can accept or reject. (What is suboptimal about this invitation-response user interface?)

    Wikis

    Wiki-wiki means quick in Hawaiian, so this is a "quickie" CSCW tool
    • "The simplest online database that could possibly work".
    • "A composition system, a discussion medium, a repository, a mail system, and a chat room". Writable web pages + MSWord-style change management.
    • Anyone can edit every page. This has proven to be a management challenge. You can delete anything you want, but others can restore it just as fast.
    • Any two or more capitalized multi-letter words (WikiWords) is a link. Adding one without a link creates a question mark.
    So, if we created a wiki for this class, how will I know when I need to go read it? An advanced Wiki would have some way to notify subscribers of new content. Given that many people might edit a Wiki page at the same time, how would a wiki keep from stomping others' work? An advanced Wiki would have versioning and auto-merging, or full-on synchronous collaborative editing.

    Virtual Communities and Collaborative Virtual Environments

    A wiki is an example of a virtual community: a persistent on-line space in which people can communicate about topics of interest. Many other forms of text-based virtual communities are out there, including USENET newsgroups, MUDs, and mailing lists.

    Another form of virtual community is the collaborative virtual environment . I gave a colloquium talk on this topic recently. Compared with a wiki, a collaborative virtual environment is:

    • a 3D graphical space
    • a powerful chat engine
    • a multiuser "virtual reality", perhaps without eyegoggles, datagloves, etc.
    • a more structured, and possibly more task-oriented, form of community
    • a supporter of coordinated (usually synchronous) interactions within some domain. The CVE may graphically support activities within this domain, which might have side-effects outside the CVE.
    A conference on CVE's has been held several times, but the field's identity remain's split between the CSCW and VR (Virtual Reality) communities.

    Possible domains: games, education, software engineering, ...

    Additional CSCW Resources

  • TU Munich has a bibliography database and a page of links

    End-of-Semester Checklist

    lecture 34 starts here

    Let's perform some arbitrary and capricious code reviews...

    ...to get you in the mood for instructor course evaluations. Remember, course evaluations are vital to the operation of our department! I might (by carefully and honestly assigning a grade you have earned) determine whether you get to repeat 384 or not, but you (by carefully and honestly evaluating the instructor and the course) not only suggest how to improve the course, but whether I should keep my job. Let's bang out those course evaluations. Did you learn anything? Why or why not? What should be done different?

    Now, onto the code reviews. Would each team please suggest a source file, or shall I pick some at random?

    lecture 35

    lecture 36

    End of Semester Presentations

    • Everyone must speak
    • Your chance to tell what you did and what you learned... in 5 minutes or less.
    • Negotiate with your team as to order, focus on individual work rather than some collective grouptalk.
    • OK to just concatenate slide, or to collaborate on slides
    • Final exam will give you a chance to reflect privately on the group experience and interactions.

    XXX Team Talks will be on YYY

    Figure you have T-2 minutes, where T=50/N

    ZZZ Team Talks will be on YYY+2

    lecture 37

    Site Quickchecks

    • PHP: nice What now ? login link, except it doesn't go to login ?
    • PHP: after logout, still says Greetings, jeffery (and missing a Login link)
    • Pygus: persistent sessions still a (major security) problem
    • Pygus: "Nude" photography subgroup probably inadvisable in university setting

    Refactoring: More Examples

    A lot of my examples will naturally come from my research efforts...

    Refactoring for Graphics Portability

    Around 1990 I wrote "a whole lot" of X Windows code to allow rapid development of visualization experiments in Icon instead of in C. The goal from the beginning was multiplatform portable (like Icon) and easy to use (like my good old TRS-80 Color Computer, where Tandy had extended Microsoft BASIC with color graphics and music).

    The different UNIX vendors that supported X11 were all using different widget toolkits, so portability was hard, even amongst Sun-vs.-HP-vs.-SGI-vs.-IBM, etc. The reasonably way I found write for all of them was to write in a lower-level X11 API called Xlib. But that wasn't portable enough: Icon ran on lots of platforms besides just UNIX. An M.S. student reimplemented all my X Windows code (on the order of 15K LOC, which had doubled the size of the Icon VM) with massive ifdef's for OS/2, proving the Icon graphics API was portable. But that wasn't portable enough: we needed MS Windows, which was mostly a knock-off of OS/2. So we refactored all the ifdef's out and defined a window-system abstraction layer: a set of C functions and macros that were needed to support the higher level Icon graphics API.

    Graphics portability is work-in-progress. Further refactoring is needed now to support Cocoa/Objective C native Apple graphics. Refactoring is also needed to support Direct3D as an alternative to OpenGL. Unicon's 3D graphics facilities were written in OpenGL by an undergraduate student, Naomi Martinez, but with the advent of Windows Vista, Microsoft messed up its OpenGL (probably deliberately) to the point where it too slow to be useful on most Windows machines.

    The OpenGL code was originally under an #ifdef Graphics3D. One initial problem was that about half that code was OpenGL-specific and half was not and could be used by Direct3D. By brute force (defining Graphics3D but disabling the includes for OpenGL header files), it was possible to identify those parts of the 3D facilities that would not compile without OpenGL. One can put all OpenGL code under an additional #ifdef HAVE_LIBGL (the symbol used in our autoconf(1) script). Just inserting some #ifdef's does not really accomplish refactoring, refactoring is when you end up modifying your function set or classes (your API) to accomodate the change. For example, the typical OO response to a need to become portable is to split a class into platform-independent parent and platform-specific child.

    Unicon 3D needed refactoring for multiple reasons. A lot of functions are ENTIRELY opengl, while others are complicated mixes. Also, the Unicon 3D facilities code was not all cleanly pulled out into a single file, it is spread/mixed into several files. Besides splitting a class, pulling code out into a few file is a common operation in refactoring.

    What happens during the Unicon3D refactor job when we realize that some of our current operations can't be feasibly done under Direct3D? What happens when we conclude that our current API doesn't let us take advantage of some special Direct3D functionality?

    Code Duplication Hell

    Unicon projects such as the CVE program from cve.sf.net are just as susceptible to lack of design or bad implementation as any other language. But how did we get to where we support four or more different copies of the Unicon language translator front-end, and 5+ different copies of the GUI widget that implements a multi-line editable textlist (text editor)? And how do we refactor our way out of this mess?

    Compiler (lexer, parser) duplications:

    uni/unicon/{unigram.y,unilex.icn,idol.icn}
    original, from the Unicon translator
    uni/parser/{unigram.y,unilex.icn,idol.icn}
    "reusable library version" by internet volunteer
    uni/ide/{unigram.y,unilex.icn,idol.icn}
    version used by an M.S. student adding syntax coloring to the Unicon IDE
    cve/src/ide/{unigram.y,unilex.icn,idol.icn}
    version used by an M.S./Ph.D. student working on CVE

    Editable Textlist Duplications:

    uni/gui/editabletextlist.icn
    original, from the Unicon GUI classes, ~1500 LOC
    uni/ide/buffertextlist.icn
    version in IDE adds optional line numbering, 921 LOC ??
    cve/src/ide/buffertextlist.icn
    base version used CVE, 357 LOC
    cve/src/ide/cetl.icn
    "collaborative" version adds network commands, 750 LOC
    cve/src/ide/syntaxetl.icn
    "syntax coloring" version, 550 LOC
    cve/src/ide/shelletl.icn
    "shell" version, adds pseudo-tty execution for execute/debug, ~1000 LOC
    cve/src/ide/scetl.icn
    multiple inheritance of syntax and collaborative, 10 LOC (factored OK)

    How did we get into this mess: it was no effort at all. Student were assigned tasks, and copy-and-modify was their natural default mode of operation.

    How do we get out: much, much harder. Student employees have resisted repeated commissionings to go refactor to eliminate the duplication. Options?

    • break everything, reimplement "right" (might not converge)
    • refactor incrementally, one method at a time

    lecture 38

    Went well:

    • Php: bug fixes, polishing navigation, writing code
    • Python: fixed lots of bugs, Damian
    Could Improve:
    • Php: finish testing, documentation, coverage
    • Python: regression avoidance, find more user-testers

    End-of-Semester Checklist

    Do you remember those neat-o forms that I passed out to you with which to give you an idea about computing your grade? Cross-reference the checklist with the syllabus weighting, which said:
    Attendance is required, as this course emphasizes collaboration. The grading will be proportioned as follows: 20% for homeworks, 20% for the midterm exam, 20% for the final exam, and 40% for a term project.

    lecture 39

    Final Examination Review

    Welcome to the final exam review day. One way to review is to go back through all of the lecture notes. Another way is to look at past exams. A third is to discuss what Dr. J really wishes you learned out of the course.

    Check out this

    Welcome to the Final Exam