Sinh PUT với Symbolic JPF

Một phần của tài liệu LUẬN VĂN:SINH CA KIỂM THỬ THAM SỐ HÓA CHO CHƯƠNG TRÌNH JAVA pdf (Trang 56 - 61)

Symbolic JPF hỗ trợ việc thực thi tượng trưng các phương thức nhận tham số đầu vào có kiểu dữ liệu là dạng số học (int, long, float, double). Từ khả năng này của Symbolic JPF ta có thể xây dựng một nền kiểm thử cho phép viết các phương thức kiểm thử tham số hóa (PUT) để kiểm thử các lớp Java đơn giản gồm các phương thức nhận tham số đầu vào có kiểu mà Symbolic JPF hỗ trợ.

Trong Java, có nền kiểm thử JUnit hỗ trợ viết và thực thi các ca kiểm thử đơn vị. Ta sẽ viết các PUT dựa trên nền kiểm thử này và xây dựng một hệ thống để thực thi các PUT đó để sinh tự động các ca kiểm thử JUnit. Với JUnit ta có thể viết các lớp kiểm thử mà chứa các ca kiểm thử đơn vị JUnit. Ta cũng có thể viết các lớp kiểm thử mà chứa các ca kiểm thử tham số hóa. Nền kiểm thử JUnit ta sử dụng là JUnit 3.8. Do đó ta cần viết các PUT để sinh ra các ca kiểm thử đơn vị JUnit tương ứng với phiên bản này. Cấu trúc của một lớp kiểm thử đối với phiên bản này như bên dưới:

import junit.framework.TestCase;

//other libraries

public class ClassName extends TestCase {

public ClassName(String name) {

super(name); }

protected void setUp() throws Exception {

super.setUp(); }

protected void tearDown() throws Exception {

super.tearDown(); }

//JUnit Test Methods ...

}

Tên của các phương thức kiểm thử JUnit bắt đầu bằng test. Nền kiểm thử JUnit quy ước điều này để xác định một phương thức là phương thức kiểm thử. Quy ước này cũng giống như ta sử dụng thuộc tính [TestMethod] để chỉ định một phương thức là một UT trong nền kiểm thử VSUnit[29] của .NET.

Ta cũng sẽ viết lớp kiểm thử tham số hóa có cấu trúc như trên. Chỉ khác rằng các ca kiểm thử đơn vị JUnit được thay thế bằng các ca kiểm thử tham số hóa. Bằng cách viết các ca kiểm thử tham số hóa dựa trên nền kiểm thử JUnit ta sẽ giảm được công sức để xây dựng lại thư viện xác nhận (assertion) và giúp việc sinh lại các ca kiểm thử đơn vị JUnit dễ dàng hơn. Ta sử dụng công cụ Eclipe Classic 3.4.2 để làm môi trường phát triển ứng dụng và viết các ca kiểm thử tham số hóa.

Với Symbolic JPF, các phương thức muốn được thực thi tượng trưng thì cần được chỉ định để Symbolic JPF có thể thực thi chúng. Việc một phương thức có được thực thi tượng trưng hay không phụ thuộc vào việc ta cấu hình để thực thi nó với JPF. Đoạn mã bên dưới sử dụng cho việc cấu hình:

// điều khiển JPF để sử dụng tập hợp các bytecode tượng trưng

+vm.insn_factory.class=gov.nasa.jpf.symbc.SymbolicInstructionFactory

// cấu hình JFF để sử dụng Listener cho việc báo cáo kết quả

+jpf.listener=gov.nasa.jpf.symbc.SymbolicListener

// cấu hình để sử dụng các thư viện toán học

+vm.peer_packages=gov.nasa.jpf.symbc:gov.nasa.jpf.jvm

// cấu hình để sử dụng bộ xử lý ràng buộc mong muốn

+symbolic.dp=iasolver

// chỉ định phương thức cần thực thi tượng trưng

+symbolic.method=UnitUnderTest(sym#sym#con)

// chỉ định lớp chứa phương thức cần thực thi tượng trưng

Main

JPF là một máy ảo do đó để có thể thực thi tượng trưng một phương thức thì lớp được chỉ định để thực thi phải chứa phương thức main. Và trong phương thức main này phương thức cần thực thi tượng trưng được gọi như bình thường với các giá trị cụ thể. Với phương thức cần thực thi tượng trưng ta cần chỉ định tên và các tham số sẽ được thực thi tượng trưng hoặc thực thi cụ thể. Giả sử như phương thức UnitUnderTest ở đoạn mã cấu hình trên thì 2 tham số đầu vào đầu tiên chỉ định cho thực thi tượng trưng, còn tham số thứ 3 sẽ thực thi cụ thể. Nếu như ta không chỉ định bộ xử lý ràng buộc được sử dụng với cấu hình +symbolic.method thì bộ xử lý ràng buộc choco[27] sẽ được sử dụng mặc định.

Ta đang muốn thực thi tượng trưng phương thức kiểm thử PUT. Lớp kiểm thử chứa các phương thức kiểm thử PUT không chứa phương thức main do đó JPF sẽ không thể thực thi nó như thông thường. Do đó thành phần PUTDriver được cài đặt để xử lý điều này. Hệ thống của ta được cài đặt để thực hiện việc cấu hình động JPF và quản lý việc thực thi của JPF qua lớp PUTListener cho việc báo cáo và sinh ra các ca kiểm thử JUnit.

Hệ thống cài đặt của ta có ưu điểm hơn so với Pex đó là ta có thể thực thi tất cả các PUT trong một lần chạy. Để thực hiện được điều này ta cần đồng bộ hóa để thực thi lần lượt các ca kiểm thử đó. Tất cả các ca kiểm thử JUnit sinh ra từ việc thực thi lớp kiểm thử chứa các ca kiểm thử tham số hóa đều được đưa vào một lớp kiểm thử JUnit. (adsbygoogle = window.adsbygoogle || []).push({});

Tuy nhiên như đã đề cập ở trên, hệ thống của ta áp dụng khả năng của Symbolic JPF để thực thi các PUT do đó chỉ các PUT nhận tham số đầu vào có kiểu số như int, float, long, double mới được thực thi. Hệ thống của ta sẽ mở rộng dễ dàng để thực thi các ca kiểm thử tham số hóa nhận các tham số đầu vào có kiểu tham chiếu khác nếu như Symbolic JPF được mở rộng để thực thi tượng trưng những phương thức như thế.

Để thực thi các ca kiểm thử tham số hóa viết cho trong môi trường Eclipse. Ta chạy run configuration và tiến hành cấu hình như sau:

Main Class : put.framework.PUTRunner

Program arguments :[<Tên lớp chứa các ca kiểm thử tham số hóa>] Giả sử có một lớp UnderTest chứa phương thức Add đơn giản như sau:

public int Add(int x, int y){ String s = “”; if(x == 2*y) { s = s + ”K50”; } if(x > y){ return x - y; } return x + y; }

Ta có một PUT là testAdd để kiểm tra việc thực thi của phương thức Add.

import junit.framework.TestCase;

import put.framework.Assume;

public class PUT extends TestCase {

void testAdd(int x, int y){ Assume.isTrue(x>0 && x<10); UnderTest ut = new UnderTest(); ut.Add(x, y);

} }

Thực thi lớp kiểm thử này ta sẽ được kết quả như hình bên dưới :

Hình 18. Một ví dụ với hệ thống cài đặt

Lớp GeneratedJUnits_by_PUT được tạo ra chứa các ca kiểm thử JUnit.

import junit.framework.TestCase;

public class GeneratedJUnits_by_PUT extends TestCase{

private PUT cls_PUT = new PUT();

public GeneratedJUnits_by_PUT(String name){

super(name); }

protected void setUp()throws Exception {

super.setUp(); }

protected void tearDown()throws Exception {

super.tearDown(); }

public void testAdd_1_minus10000(){ cls_PUT.testAdd(1, -10000); }

public void testAdd_10_x(){ cls_PUT.testAdd(10, 0); }

public void testAdd_2_1(){ cls_PUT.testAdd(2, 1); }

public void testAdd_1_1(){ cls_PUT.testAdd(1, 1); }

Một phần của tài liệu LUẬN VĂN:SINH CA KIỂM THỬ THAM SỐ HÓA CHO CHƯƠNG TRÌNH JAVA pdf (Trang 56 - 61)