Tuesday, June 05, 2007

Unit Testing in Tapestry 5

testing ใน tapestry 5 แบ่งออกเป็น 2 พวกคือ
1. พวก unit testing, สามารถใช้ได้ทั้ง testng หรือ junit
class ต่างๆที่ช่วยในการ test อยู่ใน package tapestry-core
2. พวก integrated testing, อันนี้เป็นการ test ผ่าน browser โดยใช้ selenium เข้ามาช่วย,
class ที่ช่วยในการ test อยู่ใน package tapestry-test

class ที่เป็นพระเอกในเรื่อง unit testing ก็คือ PageTester
ลองดูตัวอย่างวิธีใช้ง่ายๆ

สมมติเรามี start page หน้าตาแบบนี้
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<head>
<title>Start Page</title>
</head>
<body>
<p id="greeting">${greeting}</p>
</body>
</html>

แล้วก็มี page class หน้าตาแบบนี้
public class Start
{
@Inject
private HelloService helloService;

public String getGreeting() {
return helloService.getGreeting();
}
}

ตัว Test case ก็จะเขียนอย่างนี้
public class TestStartPage extends Assert {
@Test
public void testPage() {
String appPackage = "demo";
String appName = "Test";
PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

Document document = tester.renderPage("Start");
assertEquals("hi", document.getElementById("greeting").getChildText());
}
}

จาก code ที่เราเห็นใน class "Start" เราจะเห็นว่า
มันมีการ inject service ที่ชื่อ "HelloService" เข้ามา
ปัญหาก็คือ ในตอน run จริง, service นี้จะได้มาจาก springframework
แต่ในขั้น unit testing นี้เราไม่อยากลากเอา service ตัวจริงๆเข้ามา test ด้วย
ดังนั้น เราต้องทำการสร้าง stub ของ HelloService ขึ้นมาก่อน
public class HelloServiceStub implements HelloService {

public String getGreeting() {
return "hi";
}

}

การนำ stub ไปใช้ ก็ทำได้โดยผ่านการ configuration ด้วย Module class
package demo.services;

public class TestModule {

public static HelloService buildHelloService() {
return new HelloServiceStub();
}
}

โดยชื่อและ package ของ TestModule ต้องสัมพันธ์กับ parameter ที่เรา pass ให้ PageTester
String appPackage = "demo";        
// นำไป solve หา class โดยใช้ชื่อ class = appPackage + ".services." + appName + "Module"
String appName = "Test";
PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");


ส่วนการนำไปใช้จริง เราสามารถเขียนให้ซับซ้อน โดย simulate การ click
หรือการ submit ได้ด้วย ยกตัวอย่าง
        @Test
public void testPage() {
String appPackage = "demo.bid";
String appName = "Test";
PageTester tester = new PageTester(appPackage, appName, "src/main/webapp");

Document document = tester.renderPage("Start");

// ทดสอบ click action link
document = tester.clickLink(document.getElementById("plus"));
// assert ว่าค่าที่ render กลับมา เปลี่ยนไปอย่างที่ต้องการไหม
Node node = document.getElementById("c1").getChildren().get(1);
node = node.getChildren().get(5);
assertEquals("1", node.getChildText());
}

Related link from Roti

2 comments:

veer said...

ชอบมาก

Borut Bolčina said...

Hello,

I am very interested in how you included colored and formatted xml and java code in the blog.

Together with grey background box - this is exactly what I am looking for. I am a T5 user also.

You can contact me also at borut dot bolcina at gmail dot com.

Thanks!!!