Transcript Slide 1

Programming Methodology
•
•
•
•
•
Assertion
Testing คืออะไร
Test-Driven Development (TDD)
JUnit
JUnit Testing in Eclipse
• assertion – เงือ
่ นไขทีต
่ องเป็
นจริง ณ จุดใดจุด
้
หนึ่งของโปรแกรม
• เมือ
่ เงือ
่ นไขเป็ นเท็จ (false) จะเรียกวา่ assertion
นั้น assert
“fail” Expression1 ;
assert Expression1 : Expression2 ;
เมือ
่ “fail” จะ throw AssertionError
(1) ไมมี
่ รายละเอียด
(2) แสดงรายละเอียดตาม Expression2
• อยาใช
่
่
้ assert เพือ
– ตรวจสอบ argument ของ public method
– ทางานในคาสั่ งทีโ่ ปรแกรมตองท
า
้
assert name.remove(null); // assert can be disabled.
แกเป็
้ น
boolean nullsRemoved = name.remove(null);
assert nullsRemoved;
• เพราะเรา disable assertion ได้
• Internal Invariants
if (i % 3 == 0) {
...
} else if (i % 3 == 1) {
...
} else {
// We know (i % 3 == 2)
...
}
if (i % 3 == 0) {
...
} else if (i % 3 == 1) {
...
} else {
assert i % 3 == 2 : i;
...
}
• Control-Flow Invariants
• ใช้ในจุดทีค
่ าดวาจะไปไม
ถึ
่
่ ง (will not be reached)
assert false;
void foo() {
for (...) {
if (...)
return;
void}foo() {
// Execution
for
(...) { should never reach this point!!!
}
if (...)
return;
}
assert false; // Execution should never reach this point!
}
• Preconditions/postconditions
/**
* Sets the refresh rate. *
* @param rate refresh rate, in frames per second.
* @throws IllegalArgumentException if rate <= 0 or
* rate > MAX_REFRESH_RATE.
*/
public void setRefreshRate(int rate) {
// Enforce specified precondition in public method
if (rate <= 0 || rate > MAX_REFRESH_RATE)
throw new IllegalArgumentException("Illegal rate: " + rate);
setRefreshInterval(1000/rate);
}
• Preconditions/postcondition
/**
* Sets the refresh interval (which must correspond to a
* legal frame rate).
*
* @param interval refresh interval in milliseconds.
*/
private void setRefreshInterval(int interval)
{
// Confirm adherence to precondition in nonpublic method
assert interval > 0 && interval <=
1000/MAX_REFRESH_RATE : interval;
...
// Set the refresh interval
}
• By default, assertions are disabled at runtime.
• To enable, use the -enableassertions, or -ea, switch.
• To disable, use the -disableassertions, or -da, switch.
• no arguments - Enables or disables assertions in all classes except
system classes.
• packageName... - Enables or disables assertions in the named package
and any subpackages.
• ... - Enables or disables assertions in the unnamed package in the
current working directory.
• className - Enables or disables assertions in the named class
• For example, the following command runs a program, BatTutor, with
assertions enabled in only package com.wombat.fruitbat and its
subpackages:
java -ea:com.wombat.fruitbat... BatTutor
• กระบวนการในการเปรียบเทียบระหวาง
“ผลที่
่
ได”้ กับ “สิ่ งทีค
่ วรจะเป็ น”
• จาก IEEE Standard 610.12-1990, "IEEE Standard Glossary of
Software Engineering Terminology“
"The process of operating a system or component under specified
conditions, observing or recording the results, and making an
evaluation of some aspect of the system or component."
• Engineer ทาอะไรจะตอง
้
– มีการวางแผน
– ทาการออกแบบ
– ตามมาตรฐาน
– ลงมือทา และ
–มีแผนทดสอบ
•
•
•
•
ตองได
รั
้
้ บการออกแบบมาเป็ นอยางดี
่
Inputs คืออะไร มีอะไรบาง
้
Outputs ทีค
่ าดหวังของ input แตละตั
ว
่
Order of execution
– cascading test cases
– independent test cases
Unit Testing
Integration
Testing
Acceptance
Testing
System
Testing
• ทดสอบหน่วยทีเ่ ล็กทีส
่ ุด
ของโปรแกรม
• C++, Java  คลาส
• C  function
• ทาไปพรอมกั
บการ
้
พัฒนาโดยผู้พัฒนา
• เพือ
่ ความมัน
่ ใจใน
โปรแกรม
• ตองผ
าน
100%
้
่
Unit Testing
Integration
Testing
Acceptance
Testing
System
Testing
Unit Testing
Integration
Testing
Acceptance
Testing
System
Testing
• ประกอบ unit เขา้
ดวยกั
น แลว
้
้
ทดสอบ
• แตละ
unit อาจจะ
่
ทางานเดีย
่ วๆ ได้
ถูกตอง
แตพอมา
้
่
รวมกันอาจจะไม่
Unit
Testing
Integration
Testing
Acceptance
Testing
System
Testing
หาขอบกพร
อง
้
่
•
•
•
•
•
•
•
•
•
functionality
usability
security
i18n และ l10n
reliability/availability
capacity/performance
backup/recovery
portability
อืน
่ ๆ อีกมากมาย
Unit Testing
Acceptance
• ทดสอบโดยลูกค้า
Testing
• ตามมุมมอง และ
requirement ของลูกค้า
Integration
Testing
System
Testing
Black box
• based on requirements and specifications
• ไมต
รายละเอี
ยดภายในของโปรแกรมทีจ
่ ะ
่ องรู
้
้
ทดสอบ
White box
• ทดสอบ internal path, structure และ implementation
• ตองการความสามารถทางด
าน
Programming สูง
้
้
Grey box
• แอบดูนิดนึง จนพอเขาใจการ
implement แลว
้
้
ก็ทาตาม black box
F
• 0 - 59
D
• 60 - 69
C
• 70 - 79
B
• 80 - 89
A
• 90 - 100
• จะตองทดสอบอะไรบ
าง?
้
้
• ตองทดสอบคะแนนไหน
้
บาง?
้
• Equivalence Partitioning/Class
• Boundary Value Analysis
• มีอก
ี หลายวิธ ี (แตไม
่ ่
สอน) เช่น
–
–
–
–
–
–
all-pair testing
cause-effect
decision table
state transition
domain analysis
ฯลฯ
• ทดสอบทัง้ หมด ทาไม่
ไหว
• เปลืองแรง เวลา เงิน
และ ทรัพยากรอืน
่ ๆ
• ลดจานวนกรณีทดสอบลง โดยยังครอบคลุม
ทัง้ หมด
– แบงเป็
่ น partition/class หรือ กลุม
่
– แตละกลุ
มทดสอบสิ
่ งเดียวกัน
่
่
– ถามี
ื่ ในกลุม
้ กรณีทดสอบไหนเจอ bug กรณีอน
่
เดียวกันก็จะเจอเหมือนกัน
– ถาไม
เจอ
กรณีอน
ื่ ก็จะไมเจอ
้
่
่
• จะทดสอบกรณีไหนบาง
้
– เฉพาะ valid input หรือ
– ทัง้ valid และ invalid input
• Design by contract
– preconditions/postconditions
– ทดสอบเฉพาะ valid input
– ต.ย. มี 5 ส่วน
• Defensive design
– ทดสอบหมด
– ต.ย. มี 5 + 1 ส่วน
F
• 0 - 59
D
• 60 - 69
C
• 70 - 79
B
• 80 - 89
A
• 90 - 100
invalid input
•
อาจจะแบงเป็
่ น equivalence partition
ยอยๆ
ไดอี
่
้ ก
• แตกตางกั
นตามชนิดของ input (สาหรับ defensive
่
design)
• continuous range
– 1 valid + 2 invalids (below/above)
• discrete values within a range
– 1 valid + 2 invalids
• แตกตางกั
นตามชนิดของ input (สาหรับ defensive
่
design)
• set of input value
– 1 valid + 1 invalid
• “must be” situation
– e.g. “first character must be a letter”
– 1 valid + 1 invalid
• หา equivalence partition/class ของ
– รหัสไปรษณีย ์
– username
• ยาว ๘ อักขระ ตองขึ
น
้ ตนด
วอักษร และตองมี
้
้ วยตั
้
้
ทัง้ ตัวอักษรและตัวเลขผสมกัน
– รหัสประจาตัวนิสิต
• ๑๐ หลัก
• boundary condition
– อยูตรงขอบเขตพอดี
่
– อยูสู
1
่ งกวาขอบเขต
่
จุด
– อยูต
1
่ า่ กวาขอบเขต
่
จุด
• ของ input และ output
ของ equivalence class
• ปรับ จุดแบง่ equivalence
class
• หา boundary
value ของ
-1, 0, 1, 58, 59, 60,
ทัง้ หมด
59, 60, 61, 68, 69, 70,
69, 70, 71, 78, 79, 80,
79, 80, 81, 88, 89, 90,
89, 90, 91, 99, 100, 101
F
• 0 - 59
D
• 60 - 69
C
• 70 - 79
B
• 80 - 89
A
• 90 - 100
• Test-Driven Development (TDD) เป็ นวิธป
ี ฏิบต
ั อ
ิ ยางหนึ
่ง
่
ของ Extreme Programming (XP)
– Kent Beck และ Ron Jeffries
• ทาให้กระบวนการพัฒนาซอฟตแวร
ง์ ายขึ
น
้
์
่
กระชับขึน
้ และมีวงจรการพัฒนาอยางต
อเนื
่
่ ่อง
• Simple, Incremental Development
• Simpler Development Process
– focus on make the next test pass
• Constant Regression Testing
– full set of unit tests are tested every time a change is made.
• Improved Communication
– เขียน test กอน
ช่วยให้ทาความเขาใจ
requirement
่
้
ไดดี
้
้ ยง่ิ ขึน
Traditional development cycle
Design
Code
Test
Test
Code
Design
Test
Code
Refactor
TDD development cycle
• เป็ นเครือ
่ งมือทีใ่ ช้ช่วยในการทา unit test สาหรับ
ภาษา Java
• open source (www.junit.org, junit.sourceforge.net)
• Framework มาตรฐานสาหรับการทา unit test
สาหรับภาษา Java
• ทาการทดสอบแบบ black box
• สรางคลาสที
จ
่ ะเป็ นตัวทดสอบ
้
• ภายในคลาสจะประกอบดวยเมท็
อดตางๆ
้
่
มากมาย
• ตองการให
้
้เมท็อดไหนเป็ นกรณีทดสอบ ก็เติม
@org.junit.Test (หรือ @Test แตต
import
่ องมี
้
org.junit.Test ทีต
่ นไฟล
้
์
• สามารถเขียน 1 test method สาหรับ 1 กรณี
ทดสอบ หรือ 1 test method สาหรับหลายกรณี
ทดสอบก็ได้
– ถาเป็
้ น cascading test ก็ม ี test method ทีเ่ รียก test ยอย
่
ตามลาดับ
• เมือ
่ ตองการทดสอบค
าต
ก็จะใช้ เมท็อด
้
่ างๆ
่
org.junit.Assert.assertXXXX ทาการทดสอบ
• เติม import org.junit.Assert.*; ทีต
่ นไฟล
้
์ จะไดไม
้ ่
ตองพิ
มพชื
่ ยาว
้
์ อ
• แตละ
assert จะมีเงือ
่ นไขทีจ
่ ะเป็ นจริงแตกตางกั
น
่
่
ออกไป
• ถาไม
ผ
จะเกิด AssertionError
้
่ าน
่
assertEquals
assertFalse
assertNotNull
assertNotSame
assertNull
assertSame
assertTrue
fail
Assertion
assertTrue
assertFalse
assertNull
assertNotNull
assertEquals
assertSame
assertNotSame
fail
ผ่านเมือ่
พารามิเตอรเป็
์ น true
พารามิเตอรเป็
์ น false
พารามิเตอรเป็
์ น null
พารามิเตอรไม
่ น null
์ เป็
พารามิเตอรทั
่ ากั
่ น ตาม
์ ง้ คูเท
การเรียกใช้ equals
พารามิเตอรทั
่ อ object
์ ง้ คูคื
เดียวกัน
พารามิเตอรทั
่ นคนละ object
์ ง้ คูเป็
Fail เสมอ
• เมือ
่ ตองการทดสอบว
ามี
exception ทีค
่ าดหวัง
้
่
เกิดขึน
้ หรือไม่
• ตอนเพิม
่ @Test ให้เพิม
่ รายละเอียดดังนี้
@Test (expected=YourExpectedException.class)
• บางครัง้ เราตองสร
าง
object ของคลาสตางๆ
้
้
่
เพือ
่ ใช้ในการทดสอบหลายๆ อัน ทาให้ตอง
้
กาหนด local variable และ initialize ซา้ ๆ
เหมือนกันในหลายเมท็อด
• เปลีย
่ น local variable เหลานั
่ ้นมาเป็ น field ของ
คลาสทดสอบ
• เขียนเมท็อดทีจ
่ ะทาการ initialize field เหลานั
่ ้น
• เพิม
่ @org.junit.Before หรือ @Before (ถามี
import
้
org.junit.Before แลว)
้
• เมท็อดทีถ
่ ก
ู กาหนดดวย
@Before จะถูกเรียก
้
• ใช้ @org.junit.After หรือ @After เมือ
่ ตองการให
้
้
เมท็อดถูกเรียก หลังทุกๆ @Test เมท็อด
@Before
@Before
@Test 1
@Test 2
@Before
@After
@After
@Test N
@After
• Setup JUnit โดยการ add JUnit library ใน Java Build
Path ของโปรเจ็ค
• Demo คลาส Grade.java
• Johannes Link and Peter Frohlick, Unit Testing in Java: How tests
Drive the Code, Morgan Kaufmann Publishers, 2003.
• Russell Gold, Thomas Hammell and Tom Snyder, Test Driven
Development: A J2EE Example, Apress, 2005.
• Lee Copeland, A Practitioner's Guide to Software Test Design, Artech
House, 2004.
• Lasse Koskela, Test Driven: TDD and Acceptance TDD for Java
Developers, Manning, 2007.
• JavaTM 2 SDK, Standard Edition Documentation Version 1.4.2,
Programming With Assertions, Available:
http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html [Access July
23, 2008].