Thử nghiệm JUnit với số lượng thử nghiệm động


95

Trong dự án của chúng tôi, tôi có một số thử nghiệm JUnit , ví dụ: lấy mọi tệp từ một thư mục và chạy thử nghiệm trên đó. Nếu tôi triển khai một testEveryFileInDirectoryphương pháp trong phần TestCasenày, chỉ một bài kiểm tra có thể thất bại hoặc thành công. Nhưng tôi quan tâm đến kết quả trên từng tệp riêng lẻ. Làm cách nào để viết một TestCase/ TestSuitesao cho mỗi tệp hiển thị dưới dạng một bài kiểm tra riêng biệt, ví dụ như trong TestRunner đồ họa của Eclipse? (Mã hóa một phương pháp kiểm tra rõ ràng cho mỗi tệp không phải là một tùy chọn.)

Cũng so sánh câu hỏi ParameterizedTest với tên trong Eclipse Testrunner .


Câu trả lời:


102

Hãy xem các bài kiểm tra tham số hóa trong JUnit 4.

Trên thực tế, tôi đã làm điều này một vài ngày trước. Tôi sẽ cố gắng giải thích ...

Đầu tiên, hãy xây dựng lớp thử nghiệm của bạn một cách bình thường, giống như bạn chỉ thử nghiệm với một tệp đầu vào. Trang trí lớp học của bạn với:

@RunWith(Parameterized.class)

Xây dựng một hàm tạo lấy đầu vào sẽ thay đổi trong mọi cuộc gọi kiểm tra (trong trường hợp này, nó có thể là chính tệp)

Sau đó, xây dựng một phương thức tĩnh sẽ trả về một Collectiontrong các mảng. Mỗi mảng trong bộ sưu tập sẽ chứa các đối số đầu vào cho hàm tạo lớp của bạn, ví dụ như tệp. Trang trí phương pháp này với:

@Parameters

Đây là một lớp mẫu.

@RunWith(Parameterized.class)
public class ParameterizedTest {

    private File file;

    public ParameterizedTest(File file) {
        this.file = file;
    }

    @Test
    public void test1() throws Exception {  }

    @Test
    public void test2() throws Exception {  }

    @Parameters
    public static Collection<Object[]> data() {
        // load the files as you want
        Object[] fileArg1 = new Object[] { new File("path1") };
        Object[] fileArg2 = new Object[] { new File("path2") };

        Collection<Object[]> data = new ArrayList<Object[]>();
        data.add(fileArg1);
        data.add(fileArg2);
        return data;
    }
}

Cũng kiểm tra ví dụ này


1
Cảm ơn! Phương pháp JUnit 4 tốt hơn Phương pháp JUnit 3 được đưa ra trong một câu trả lời khác, vì JUnit 3 gây nhầm lẫn cho người chạy thử nghiệm nhật thực và với Phương pháp JUnit 4, bạn có thể thực hiện lại các bài kiểm tra, v.v. Tôi chỉ tự hỏi làm thế nào tôi có thể hiển thị nhật thực tên cho bài kiểm tra - nó chỉ hiển thị [0], [1], v.v.
Hans-Peter Störr 12/12/08

@hstoerr, Có vẻ như phần này sẽ có trong bản phát hành tiếp theo của JUnit :-) github.com/KentBeck/junit/commit/…
rescdsk

Bạn sẽ biến đổi điều này như thế nào nếu bạn muốn mỗi lần chạy [với một kết hợp dữ liệu khác nhau] sửa đổi tên của lần chạy thử nghiệm của chúng? [Tức là tệp Path1 sẽ được kiểm tra dưới dạng: test1Path1, test2Path?
Mony


27

JUnit 3

public class XTest extends TestCase {

    public File file;

    public XTest(File file) {
        super(file.toString());
        this.file = file;
    }

    public void testX() {
        fail("Failed: " + file);
    }

}

public class XTestSuite extends TestSuite {

    public static Test suite() {
        TestSuite suite = new TestSuite("XTestSuite");
        File[] files = new File(".").listFiles();
        for (File file : files) {
            suite.addTest(new XTest(file));
        }
        return suite;
    }

}

JUnit 4

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class TestY {

    @Parameters
    public static Collection<Object[]> getFiles() {
        Collection<Object[]> params = new ArrayList<Object[]>();
        for (File f : new File(".").listFiles()) {
            Object[] arr = new Object[] { f };
            params.add(arr);
        }
        return params;
    }

    private File file;

    public TestY(File file) {
        this.file = file;
    }

    @Test
    public void testY() {
        fail(file.toString());
    }

}

11

Junit 5 Kiểm tra tham số

Kiểm tra tham số JUnit 5 hỗ trợ điều này bằng cách cho phép sử dụng một phương pháp làm nguồn dữ liệu :

@ParameterizedTest
@MethodSource("fileProvider")
void testFile(File f) {
    // Your test comes here
}

static Stream<File> fileProvider() {
    return Arrays.asList(new File(".").list()).stream();
}

JUnit 5 DynamicTests

JUnit 5 cũng hỗ trợ điều này thông qua khái niệm a DynamicTest, sẽ được tạo trong a @TestFactory, bằng phương thức tĩnh dynamicTest.

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

import java.util.stream.Stream;

@TestFactory
public Stream<DynamicTest> testFiles() {
    return Arrays.asList(new File(".").list())
            .stream()
            .map((file) -> dynamicTest(
                    "Test for file: " + file,
                    () -> { /* Your test comes here */ }));
}

Các bài kiểm tra chạy trong IDE của bạn (IntelliJ tại đây) sẽ được hiển thị như sau:

Đầu ra trong IntelliJ


3

Có thể thực hiện được trong JUnit 3 bằng cách kế thừa từ TestSuitevà ghi đè tests()phương thức để liệt kê các tệp và mỗi lần trả về một thể hiện của một lớp con củaTestCase có tên tệp làm tham số phương thức khởi tạo và có một phương thức kiểm tra để kiểm tra tệp được cung cấp trong hàm tạo.

Trong JUnit 4, nó có thể dễ dàng hơn.


2

Bạn có thể cân nhắc sử dụng thư viện JUnitParams , vì vậy bạn sẽ có thêm một số tùy chọn (sạch hơn):

@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class)
public class ParameterizedTest {

    @org.junit.Test
    @junitparams.Parameters(method = "data")
    public void test1(File file) throws Exception {  }

    @org.junit.Test
    @junitparams.Parameters(method = "data")
    public void test2(File file) throws Exception {  }

    public static File[] data() {
        return new File[] { new File("path1"), new File("path2") };
    }
}

@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class)
public class ParameterizedTest {

    @org.junit.Test
    @junitparams.Parameters(value = { "path1", "path2" })
    public void test1(String path) throws Exception {
        File file = new File(path);
    }

    @org.junit.Test
    @junitparams.Parameters(value = { "path1", "path2" })
    public void test2(String path) throws Exception {
        File file = new File(path);
    }
}

Bạn có thể xem thêm các mẫu sử dụng tại đây .

Ngoài ra về JUnitParams, tại sao việc ghi các bài kiểm tra tham số hóa với nó lại dễ dàng và dễ đọc hơn :

Dự án JUnitParams thêm một trình chạy mới vào JUnit và cung cấp các bài kiểm tra tham số dễ đọc và dễ đọc hơn nhiều cho JUnit> = 4.6.

Sự khác biệt chính đối với Á hậu JUnit Parametrised tiêu chuẩn:

  • rõ ràng hơn - các tham số nằm trong các tham số phương pháp thử nghiệm, không phải trường lớp
  • ít mã hơn - bạn không cần một hàm tạo để thiết lập các tham số
  • bạn có thể kết hợp các tham số với các phương thức không tham số trong một lớp
  • tham số có thể được truyền dưới dạng chuỗi CSV hoặc từ lớp trình cung cấp tham số
  • lớp trình cung cấp tham số có thể có bao nhiêu tham số cung cấp các phương thức tùy thích để bạn có thể nhóm các trường hợp khác nhau
  • bạn có thể có một phương thức kiểm tra cung cấp các tham số (không có lớp bên ngoài hoặc tĩnh nữa)
  • bạn có thể thấy các giá trị tham số thực tế trong IDE của mình (trong Tham số của JUnit, nó chỉ là các số tham số liên tiếp)

1

Nếu TestNG là một tùy chọn, bạn có thể sử dụng Tham số với DataProviders .

Kiểm tra của từng tệp riêng lẻ sẽ có kết quả của nó được hiển thị trong báo cáo dựa trên văn bản hoặc giao diện người dùng plugin TestNG của Eclipse. Tổng số lần chạy thử nghiệm sẽ tính riêng từng tệp của bạn.

Hành vi này khác với JUnit Theories , trong đó tất cả các kết quả được gộp chung dưới một mục "lý thuyết" và chỉ được tính là 1 bài kiểm tra. Nếu bạn muốn báo cáo kết quả riêng biệt trong JUnit, bạn có thể thử Kiểm tra tham số .

Kiểm tra và đầu vào

public class FileTest {

    @DataProvider(name="files")
    public File[][] getFiles(){
        return new File[][] {
            { new File("file1") },
            { new File("file2") }
        };
        // or scan a directory
    }

    @Test(dataProvider="files")
    public void testFile(File file){
        //run tests on file
    }
}

Ví dụ đầu ra

PASSED: testFile(file1)
PASSED: testFile(file2)

===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================

Tôi không biết về lý thuyết, nhưng các bài kiểm tra tham số hóa trong JUnit được hiển thị riêng biệt trong nhật thực, không gộp chung với nhau.
Hans-Peter Störr

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.