User:Hyad/SE/Test2
Testing
http://www.se.rit.edu/~se361/slides/Testing.pdf
- A failure is an unacceptable behaviour exhibited by a system
- A defect is a flaw in any aspect of the system that contributes,
or may potentially contribute, to the occurrence of one or more failures
- An error is a slip-up or inappropriate decision by a software
developer that leads to the introduction of a defect
Black-box testing
--Also called 'concrete box' or 'functional' testing
- Testers provide the system with inputs and observe the
outputs
- Tester is only given interface
- Tester doesn't know what is behind it
Glass-box testing
--Also called ‘white-box’ or ‘structural’ testing
- Testers have access to the system design
- They can view the code
- Individual programmers often informally employ glassbox
testing to verify their own code
Equivalence classes
- It is inappropriate to test by brute force, using every
possible input value- Takes a huge amount of time -Is pointless!
- You should divide the possible inputs into groups which
you believe will be treated similarly by all algorithms.
- Ex.Valid input is a month number (1-12), Equivalence classes are: [-∞..0], [1..12], [13.. ∞]
- Testing at boundaries of equivalence
classes - More errors in software occur at the boundaries of equivalence classes
Acceptance tests
-Performed by user to see if it meets their requirements -Acceptance tests are black box tests that cover all the requirements -For the project, you will need to create acceptance tests
Stubs and Drivers
-used to replace classes the aren't finished
- Driver=replacement for the class that calls the module we are testing
- A routine that calls the module and passes it appropriate test input values
- We will use JUnit drivers for our unit testing
- Stub=replacement for the class that is called by the module we are testing
- Ex. A call that is supposed to do WriteScoreToFile() might be
replaced by a stub that did nothing
Test Case and Test Plan
- A test case is an explicit set of instructions designed to
detect a particular class of defect in a software system.
- A test plan is a document that contains a collection of test cases for a system
- The test plan should be written long before the testing starts.
- You can start to develop the test plan once you have developed the
requirements.
EX.
Test Case 2001 System: SimpleChat Phase: 2 Server startup check with default arguments Severity: 1 Instructions: . At the console, enter: java EchoServer. Expected result: 1. The server reports that it is listening for clients by displaying the following message: Send socket connetion Server listening for clients on port 5555 . The server console waits for user input. Cleanup: . Hit CTRL+C to kill the server.
9/22/05 http://www.se.rit.edu/~se361/slides/DesignFundamentals.pdf
Software Design
- Good design is about finding the best option among a space
of design possibilities
- The quality of a design is determined by how well it
addresses the key non-functional requirements
- Ex: Extensibility, modifiability, usability, performance etc.
Design Aspects
- Architecture design:
- The division into subsystems and components,
- How these will be connected.
- How they will interact.
- Their interfaces.
- Class design:
- User interface design
- Algorithm design:
- The design of computational mechanisms.
- Protocol design:
- The design of communications protocol.
Cohesion & Coupling
Important - should know def.
- Increase cohesion (keep related stuff together)
- Decrease coupling (minimize dependencies between modules)
- A good abstraction provides information hiding
Coupling
Coupling occurs when there are interdependencies between one module and another
- When interdependencies exist, changes in one place will require
changes somewhere else.
- network of interdependencies makes it hard to see at a glance
how some component works.
- You want to reduce coupling; reduce interdependencies.
Cohesion
Cohesion is how well related modules are kept together
- Modules with high cohesion tend to be preferable because high cohesion is associated with several desirable traits of software including robustness, reliability, reusability, and understandability
- Whereas low cohesion is associated with undesirable traits such as difficult to maintain, difficult to reuse, and difficult to understand.
- You want to increase cohesion
Abstraction
Keeping the level of abstraction high
Abstraction = hiding information so code is easier to understand & uncomplicated
- Ensure that your designs allow you to hide or defer
consideration of details, thus reducing complexity
- A good abstraction provides information hiding
- Fewer public methods, no public data
- Abstractions allow you to understand the essence of a
subsystem without having to know unnecessary details
- It avoids constraining the design of other modules e.g.
DisplayPopupMenu() vs. DisplayMenu() vs. DisplayCommandList()
4 things we need to know
- Coupling (interdependecies) - decrease
- Cohesion (how are modules related) - increase
- Abstraction (hide complicated info) - increase
- Contract (each method has an explicit contract with its callers)
Designs
Designing for flexibility
--Keep things general as possible
- Actively anticipate changes that a design may have to
undergo in the future, and prepare for them
- Do not hard-code anything
- Leave all options open
- Do not restrict the options of people who have to modify the
system later
- Use reusable code and make code reusable
Anticipating obsolescence
- Plan for changes in the technology or environment so the
software will continue to run or can be easily changed
- Avoid using software libraries that are specific to
particular environments
- Avoid using software or special hardware from
companies that are less likely to provide long-term support
- Use standard languages and technologies that are
supported by multiple vendors
Designing for Testability
- Take steps to make testing easier
- Design a program to automatically test the software
- Ensure that all the functionality of the code can by
driven by an external program, bypassing a graphical user interface
- In Java, you can create a main() method in each class
in order to exercise the other methods
Design by contract
- A technique that allows you to design defensively in an
efficient and systematic way
- Key idea = each method has an explicit contract with its callers
- The contract has a set of assertions that state:
- What preconditions the called method requires to be true
when it starts executing
- What postconditions the called method agrees to ensure
are true when it finishes executing
- What invariants the called method agrees will not change
as it executes
Multi-layer architecture and design principles
- Divide and conquer: The layers can be independently
designed.
- Reduce coupling: Lower layers have no dependency on the
higher layers.
- Increase flexibility: you can add new facilities built on lowerlevel
services, or replace higher-level layers.
- Design for portability: All the dependent facilities can be
isolated in one of the lower layers.
- Design for testability: Layers can be tested independently.
- Design defensively: The APIs of layers are natural places to
build in rigorous assertion-checking.
http://www.se.rit.edu/~se361/slides/DesignFundamentals.pdf
9/27
Multi-Layer Pattern
- In a layered system, each layer communicates only with the layer
immediately below it.
- Each layer has a well-defined interface used by the layer
immediately above.
- ->The higher layer sees the lower layer as a set of services.
- A complex system can be built by superposing layers at increasing
levels of abstraction.
- It is important to have a separate layer for the UI.
- Layers immediately below the UI layer provide the application
functions determined by the use-cases.
- Bottom layers provide general services.
- e.g. network communication, database access
Model-View-Controller (MVC) Pattern
Definition: MVC = an architectural pattern used to help separate the user interface layer from other parts of the system
- The model contains the underlying classes whose
instances are to be viewed and manipulated
- The view contains objects used to render the appearance
of the data from the model in the user interface
- The controller contains the objects that control and
handle the user’s interaction with the view and the model
- The Observable design pattern (design patterns
discussed later in the course) is normally used to separate the model from the view
Input --> Processing --> Output
Controller --> Model --> View
Steps
- Controller recieves actor events
- Controller modifies Model, Controller creates and updates View
- Model notifies changes to the View
- View is viewed by actor
- (The process is repeated)
JUnit
http://www.se.rit.edu/~se361/slides/JUnit.pdf
- Unit – “natural” abstraction unit of an O abstraction unit of an Obj. Oriented system: class or its instantiated form, object. system: class or its instantiated form, object.
- Unit Tests – verify a small chunk of code, verify a small chunk of code, typically a path through a method or function. typically a path through a method or function.
Why is Unit Testing Good?
- Identifies defects early in the development cycle.
- Many small bugs ultimately leads to chaotic system behavior system behavior
- Testing affects the design of your code.*Successful tests breed confidence.
- Testing forces us to read our own code – spend more time reading than writing
- Automated tests support maintainability & extendibility.
Key JUnit Concepts
- assert
- assertEquals( expected, actual ) – also NotEquals
- assertNull( actual result ) – also NotNull
- assertTrue( actual result) - also False
- failures –
- Exceptions raised by asserts (expected)
- errors –
- Java runtime exceptions (not expected)
JUnit example
import junit.framework.TestCase;
public class MovieListTest extends TestCase {
public static void main(String[] args) {
junit.textui.TestRunner.run(MovieListTest.class);
}
public void testEmptyListSize(){
MovieList emptyList = new MovieList();
assertEquals( "Size of empty list should be 0.", 0, emptyList.size());
}
public void testSizeAfterAddingOne(){
Movie starWars = new Movie();
MovieList oneItemList = new MovieList();
oneItemList.add( starWars);
assertEquals( "Size of one item list should be 1.", 1, oneItemList.size());
}
public void testSizeAfterAdddingTwo(){
Movie starWars = new Movie();
Movie starTrek = new Movie();
MovieList twoItemList = new MovieList();
twoItemList.add(starWars);
twoItemList.add(starTrek);
assertEquals("Size of a two item list should be 2.", 2, twoItemList.size());
}
}