90c3c68619e9f667746ac27a11fa98ba.ppt
- Количество слайдов: 74
Object-Oriented Design and Programming (Java)
Topics Covered Today • • Overview of Software Testing Methods Software Test Types 2. 1 Implementing Classes – 2. 1. 4 Unit Testing 2
Overview of Software Testing • Purpose of Software Testing • Role of Testers • Truths and Realities 3
Software Testing • Any activity designed to evaluate an attribute or capability of a program to determine that it meets required standards. 4
Purpose of Software Testing • Measure Quality – Validation确认: Prove it works (Do the right thing) – Verification证明: Do it right • Provide information – To development and management – For risk evaluation • Watching the process not just the product 5
Software Quality • Doing the right things right at the right time • Conformance to applicable standards – Customer focus • Features vs. Flaws – Engineering focus • Maintainability, sustainability可维护, testability, etc. • Quality is defined as conformance一致 to requirements, not as “goodness” or “elegance” • Quality also means “meet customer needs” 6
Role of Testers • • Find Bugs Break Software Keep Developers Honest Defect Prevention Quality Measurement Drive quality upstream Customer focus Goal: ensure the quality 7
Truths and Realities • The earlier a bug is fixed, the less costly it is. – Before code review – By testing – By Beta testers – After product is released • Prevention vs. Detection – “The mere act of designing a test is a powerful bug preventer” 8
Truths and Realities • Thorough Testing vs. Risk-based testing – Thorough Testing: testing for everything – Risk-based Testing • Identify and analyze risks to enable informed and calculated decisions • Look for the best use of test resource • Risks can be categorized by severity and likelihood. 9
Software Testing Methods • Black-box Testing • White-box Testing • Risk-based Testing 10
Black-box Testing • Doesn’t require explicit knowledge of the internal structure of the system • Primarily focuses on functional requirements – User-perspective – Validates the spec Input Output 11
White-box testing • Requires knowledge of the internal structure • Primarily focuses on code coverage – e. g. write tests to “cover” internal paths – Good for testing individual functions – Developer’s tests Input Output 12
Risk-based Testing • Used to determine: – What to test – Test priority – Test coverage 13
Risk-based Testing 14
Risk-based Testing • Two basic factors for determining risk: – Impact to the customer – Probability of customer experiencing issues • Other factors affecting risk assessment: – History, complexity, usability, dependencies, new features or technologies, modifications, etc. • Value of Risk Assessment – Prioritize work – Scope testing effort 15
Software Test Types • 基于是否需要执行被测试软件 – Dynamic Test动态测试、Static Test静态测试; • 基于是否关注软件结构与算法 – Black Box Test、White Box Test • 基于测试的不同阶段 – Unit testing单元测试、 Integration testing集成测试、 System testing系统测试、 Acceptance testing验收测试; • 其它 – Smoke Test冒烟测试、 Regression Test回归测试、 Functional Test功能测试、Stress Test负载测试(压力测试)、 Performance Test 性能测试、 Accessibility Test易用性测试、Install/Uninstall Test安 装与反安装测试、 Security Test安全性测试、 Application Compatibility Test兼容性测试、Alpha测试、Beta测试等 16
Test Stages Requirement specification Acceptance testing (用户需求) (验收测试) System specification System testing (规格定义) (系统测试) Design (设计) Integration testing (集成测试) Code (编码) Unit testing (单元测试) 17
BVT(Build Verification Test) • An automated test suite run on each new build to validate the integrity of the build and basic functionality before the new build is released for general testing. – Also known as build acceptance test(构建验证测试 ). • Advantages – Save testing time – Validate basic functionality • Disadvantages – Minimum level of test coverage 18
Application Compatibility Test • Test 3 rd-party application behavior and integration with new software • Advantages – Exercise application interaction – Customer focused • Disadvantages – Testers not usually experts in all application software – Impossible to test all applications or interactions 19
Scenario Tests • Tests that simulate customers’ real usage • Advantages – Customer focused • Disadvantages – Difficult to simulate 20
Software Testing • Important and expensive activity – Not unusual to spend 30 -40% of total project effort on testing – For critical systems (e. g. flight control): cost can be several times the cost of all other activities combined 21
Test Planning • Why Test Plan • What’s in a Test Plan • How to write a test plan 22
Benefits of Writing Test Plan • Improves test coverage and efficiency • Improves communication among peers, teams and with management – Feedback • Helps manage testing • Improves individual accountability 23
What’s in a Test Plan • • Who will be doing the work What will be tested What will NOT be tested Test environments (hardware/software) Test strategy Test dependency Test groups/categories Risks/Open Issues 24
Test Development • Characteristics of Good Tests – Reasonable probability of catching an error – Not redundant – Be focused • Development Techniques – Boundary Value Analysis – Error Guessing/Exploratory Testing • Test Case Documentation 25
Test Case • A test case(测试用例) is a document that describes an input, action, or event and an expected response, to determine if a feature of an application is working correctly • Test case: specifies – Inputs + pre-test state of the software – Expected results (outputs and state) 26
Bug Report – Bad Example Title: AV occurs. Description: An AV occurs when running test 2641. Repro Steps: 1) Run test 2641 27
Mistakes to Avoid • • • Incomplete repro steps Lack of details and investigation Missing environment/configuration info Missing expected result Duplicate bugs 28
Good Testers • • Good knowledge of computer science Knowledge of one or more programming languages Debugging skills Attention to details Ability to prioritize work Team player Good communication skills 29
Topics Covered Today • • Overview of Software Testing Methods Software Test Types 2. 1 Implementing Classes – 2. 1. 4 Unit Testing 30
Unit Testing • • scope = individual component Focus: component correctness Responsibility of the developer White-box and black-box techniques 31
Example: Hello World Program • Use main method to test class “Hello. World” • Testing plan: – Instance of Hello. World. java should not be null – Output should be “Hello World” 32
Hello. World. java code public class Hello. World { public String say. Hello() { System. out. println("Hello World"); return “Hello World”; } public static void main( String[] args ) { Hello. World world = new Hello. World(); world. say. Hello(); } } 33
Create a New Class for Testing public class Hello. World { String say. Hello() { return "Hello World!"; } } public class Test. Hello. World { public static void main(String[] args) { Hello. World world = new Hello. World(); String result = world. say. Hello(); if (result. equals("Hello World!") == false) { System. out. println("Bad result: " + result); } } } 34
Example 2 • Another example to create a new class for testing (see 2. 1. 4 Unit Testing). – Bank. Account. java – Test. Bank. Account. java 35
Class Bank. Account public class Bank. Account { private double balance; public Bank. Account() { balance = 0. 0; } public double get. Balance() { return balance; } public boolean deposit(double amount) { if (amount > 0) { balance += amount; return true; } else { return false; } } public boolean withdraw(double amount) { if (amount > 0 && balance >= amount) { balance -= amount; return true; } else { return false; } }} 36
Class Test. Bank. Account import java. io. *; public class Test. Bank. Account { private static Print. Writer std. Out = new Print. Writer(System. out, true); private static Print. Writer std. Err = new Print. Writer(System. err, true); public static void assert. True(String message, boolean condition) { if (! condition) { std. Err. print("** Test failure "); std. Err. println(message); } } public static void main(String[] args) { boolean result; // Testing constructor and accessor Bank. Account account. One = new Bank. Account(); assert. True("1: testing method get. Balance()", account. One. get. Balance() == 0); 37
Class Test. Bank. Account //Testing method deposit Bank. Account account. Two = new Bank. Account(); result = account. Two. deposit(100); assert. True("2: testing method deposit", result); assert. True("3: testing method deposit", account. Two. get. Balance() == 100); result = account. Two. deposit(50); assert. True("4: testing method deposit", result); assert. True("5: testing method deposit", account. Two. get. Balance() == 150); result = account. Two. deposit(0); assert. True("6: testing method deposit", ! result); assert. True("7: testing method deposit", account. Two. get. Balance() == 150); result = account. Two. deposit(-25); assert. True("8: testing method deposit", !result); assert. True("9: testing method deposit", account. Two. get. Balance() == 150); 38
Class Test. Bank. Account //Testing method withdraw Bank. Account account. Three = new Bank. Account(); account. Three. deposit(100); result = account. Three. withdraw(60); assert. True("10: testing method withdraw", result); assert. True("11: testing method withdraw", account. Three. get. Balance() == 40); result = account. Three. withdraw(50); assert. True("12: testing method withdraw", ! result); assert. True("13: testing method withdraw", account. Three. get. Balance() == 40); result = account. Three. withdraw(0); assert. True("14: testing method withdraw", ! result); assert. True("15: testing method withdraw", account. Three. get. Balance() == 40); result = account. Three. withdraw(-10); assert. True("16: testing method withdraw", ! result); assert. True("17: testing method withdraw", account. Three. get. Balance() == 40); std. Out. println("done"); }} 39
A (slightly) better Test. Hello. World program public class Test. Hello. World { private int nb. Errors = 0; public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); if (result. equals("Hello World!") == false) { throw new Runtime. Exception("Bad result: " + result); } } 40
A (slightly) better Test. Hello. World program public static void main(String[] args) { Test. Hello. World test = new Test. Hello. World(); try { test. Say. Hello(); } catch (Throwable e) { test. nb. Errors++; e. print. Stack. Trace(); } if (test. nb. Errors > 0) { throw new Runtime. Exception ("There were " + test. nb. Errors + " error(s)"); } } } 41
Advantage • Move the test into its own method. – It’s now easier to focus on what the test does. – You can also add more methods with more unit tests later, without making the main block harder to maintain. • Change the main block to print a stack trace when an error occurs and then, if there any errors, to throw a summary exception at the end. 42
JUnit • JUnit is a framework for performing unit testing on programs – A unit test is a test of a single class • A test case(测试用例) is a single test of a single method • A test suit(测试系列) is a collection of test cases • Available as a stand-alone application and build into Eclipse • Framework executes the test cases and records the results – Displays results in a GUI 43
Why JUnit • • • Allow you to write code faster while increasing quality Elegantly simple Check their own results and provide immediate feedback Tests is inexpensive Increase the stability of software Developer tests Written in Java Free Gives proper understanding of unit testing 44
New->Other->Java->JUnit Test Case 45
Create New JUnit Test Case 46
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World!", result); } } 47
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World!", result); } } 1. You start by extending the test class from the standard Junit junit. framework. Test. Case. This base class includes the framework code that JUnit needs to automatically run the tests. 48
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World!", result); } } 2. You make sure that the method name follows the pattern test. XXX(). Following the test. XXX naming convention is not strictly required, but it is strongly encouraged as a best practice. 49
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World!", result); } } 3. You start the test by creating an instance of the Hello. World class (the “object under test”), 50
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World!", result); } } 4. You execute the test by calling the method to test, no parameter is passing in this case. 51
Test. Hello. World program written with JUnit 3. x import junit. framework. Test. Case; public class Test. Hello. World extends Test. Case { public void test. Say. Hello() { Hello. World world = new Hello. World(); String result = world. say. Hello(); assert. Equals("Hello World", result); } 5. }To check the result of the test, you call an assert. Equals method, which inherited from the base Test. Case. static void assert. Equals([String message], expected, actual) 52
JUnit for Eclipse 53
Successful Test 54
Failed Test Hello World. 多了一个句点符号 55
JUnit Methods • assert. Equals(x, y) – Test passes if x and y are equal – x and y can be primitives or any type with an appropriate equals method – Three argument versions exist for floating point numbers • • • assert. False(b) – Test passes if boolean value b is false assert. True(b) – Test passes if boolean value b is true assert. Null(o) – Test passes if object o is null assert. Not. Null(o) – Test passes if object o is not null assert. Same(ox, oy) – Test passes if ox and oy refer to the same object • assert. Not. Same(ox, oy) – Test passes if ox and oy do not refer to the same object 56
JUnit Test Runner Sequence • Test runner(测试 运行程序) is given a list of test classes • For each test class Create an instance of the test class For each test*() method Run set. Up() method // code run before every test Run test method steps and checks If a check fails, an assertion is thrown and the testmethod fails Run tear. Down() method • Test runner produces a report 57
Things to Notice • The set. Up() method ensures you entered the test method with a virgin set of objects. – Officially called “test fixtures(测试固件)”. – It is just a some code you want run before every test • The tear. Down() method frees memory, prevents results of one test from affecting the next. – It will be run after every test case • Only the first failure in a test method is reported – Don’t do too much in a single test 58
Implementing set. Up() method • Override set. Up() to initialize the variables, and objects • Since set. Up() is your code, you can modify it any way you like (such as creating new objects in it) • Reduces the duplication of code 59
Implementing the tear. Down() method • In most cases, the tear. Down() method doesn’t need to do anything – The next time you run set. Up(), your objects will be replaced, and the old objects will be available for garbage collection – Like the finally clause in a try-catch-finally statement, tear. Down() is where you would release system resources (such as streams) 60
the Structure of a Test Method • A test method doesn’t return a result • If the tests run correctly, a test method does nothing • If a test fails, it throws an Assertion. Failed. Error • The JUnit framework catches the error and deals with it; you don’t have to do anything 61
Test suites • In practice, you want to run a group of related tests. To do so, running test suites. import junit. framework. Test; import junit. framework. Test. Suite; public class All. Tests { public static Test suite() { Test. Suite suite = new Test. Suite("Test for default package"); suite. add. Test. Suite(Test. String. Util. class); suite. add. Test. Suite(Test. Hello. World. class) return suite; } } 62
Creating a test class in JUnit • Define a subclass of Test. Case • Override the set. Up() method to initialize object(s) under test. • Override the tear. Down() method to release object(s) under test. • Define or more public test. XXX() methods that exercise the object(s) under test and assert expected results. • Define a static suite() factory method that creates a Test. Suite containing all the test. XXX() methods of the Test. Case. • Optionally define a main() method that runs the Test. Case in batch mode. 63
Start to Use it • Download the latest version of JUnit from http: //download. sourceforge. net/junit/ • Installation – unzip the junit. zip file – add junit. jar to the CLASSPATH. 64
the Framework of JUnit 65
the Framework of JUnit Package junit. framework 66
the Framework of JUnit Package junit. runner 67
the Framework of JUnit A set of assert methods. Messages are only displayed when an assert fails. 68
the Framework of JUnit A Test. Failure collects a failed test together with the caught exception. A Test. Result collects any errors or failures that occur during a test. 69
the Framework of JUnit A Test can be run and passed a Test. Result. 70
the Framework of JUnit A Test. Listener is apprised of events that occur during a test, including when the test begins and ends, along with any errors or failures. 71
the Framework of JUnit A Test. Case defines an environment (or fixture) that can be used to run multiple tests. 72
the Framework of JUnit A Test. Suite runs a collection of test cases, which may include other test suites. It is a composite of Tests. 73
the Framework of JUnit A test runner is a user interface for launching tests. Base. Test. Runner is the superclass for all test runners. 74
90c3c68619e9f667746ac27a11fa98ba.ppt