Làm thế nào để kiểm tra khi sắp xếp dữ liệu quá cồng kềnh?


19

Tôi đang viết một trình phân tích cú pháp và là một phần trong đó, tôi có một Expanderlớp "mở rộng" một câu lệnh phức tạp thành nhiều câu lệnh đơn giản. Ví dụ, nó sẽ mở rộng điều này:

x = 2 + 3 * a

vào:

tmp1 = 3 * a
x = 2 + tmp1

Bây giờ tôi đang suy nghĩ về cách kiểm tra lớp này, cụ thể là cách sắp xếp các bài kiểm tra. Tôi có thể tự tạo cây cú pháp đầu vào:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

Hoặc tôi có thể viết nó dưới dạng một chuỗi và phân tích nó:

var input = new Parser().ParseStatement("x = 2 + 3 * a");

Tùy chọn thứ hai đơn giản hơn nhiều, ngắn hơn và dễ đọc hơn. Nhưng nó cũng giới thiệu một sự từ chối Parser, điều đó có nghĩa là một lỗi trong Parsercó thể thất bại trong bài kiểm tra này. Vì vậy, bài kiểm tra sẽ dừng là một bài kiểm tra đơn vị Expandervà tôi đoán về mặt kỹ thuật sẽ trở thành một bài kiểm tra tích hợp ParserExpander.

Câu hỏi của tôi là: có ổn không khi dựa chủ yếu (hoặc hoàn toàn) vào loại kiểm tra tích hợp này để kiểm tra Expanderlớp này ?


3
Rằng một lỗi trong Parsercó thể thất bại một số thử nghiệm khác không phải là vấn đề nếu bạn thường xuyên chỉ cam kết ở mức không có lỗi, ngược lại, điều đó có nghĩa là bạn có phạm vi bảo hiểm nhiều hơn Parser. Điều tôi thà lo lắng là một lỗi trong Parsercó thể làm cho thử nghiệm này thành công khi đáng lẽ nó phải thất bại . Các bài kiểm tra đơn vị ở đó để tìm lỗi, sau khi tất cả các bài kiểm tra bị hỏng khi không có nhưng nên có.
Jonas Kölker

Câu trả lời:


27

Bạn sẽ thấy mình viết nhiều bài kiểm tra hơn, về hành vi phức tạp, thú vị và hữu ích hơn nhiều, nếu bạn có thể làm như vậy một cách đơn giản. Vì vậy, tùy chọn liên quan đến

var input = new Parser().ParseStatement("x = 2 + 3 * a");

là khá hợp lệ. Nó không phụ thuộc vào thành phần khác. Nhưng mọi thứ phụ thuộc vào hàng tá các thành phần khác. Nếu bạn chế nhạo thứ gì đó trong vòng một inch của cuộc đời, có lẽ bạn phụ thuộc vào rất nhiều tính năng chế giễu và đồ đạc thử nghiệm.

Các nhà phát triển đôi khi quá tập trung vào sự tinh khiết của đơn vị xét nghiệm của họ , hoặc phát triển các bài kiểm tra đơn vị và kiểm tra đơn vị duy nhất , mà không cần bất kỳ mô-đun, hội nhập, căng thẳng hoặc các loại bài kiểm tra. Tất cả các hình thức này là hợp lệ và hữu ích, và chúng đều là trách nhiệm đúng đắn của các nhà phát triển - không chỉ là Q / A hay nhân viên vận hành ở xa hơn.

Một cách tiếp cận tôi đã sử dụng là bắt đầu với các lần chạy cấp cao hơn này, sau đó sử dụng dữ liệu được tạo từ chúng để xây dựng biểu thức mẫu số dài, phổ biến thấp nhất của thử nghiệm. Ví dụ: khi bạn kết xuất cấu trúc dữ liệu từ inputsản xuất ở trên, thì bạn có thể dễ dàng xây dựng:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

loại kiểm tra mà kiểm tra ở mức rất thấp. Bằng cách đó, bạn có được một kết hợp tốt đẹp: Một số ít các bài kiểm tra cơ bản, cơ bản nhất (bài kiểm tra đơn vị thuần túy), nhưng đã không dành một tuần để viết bài kiểm tra ở cấp độ nguyên thủy đó. Điều đó cung cấp cho bạn nguồn thời gian cần thiết để viết nhiều bài kiểm tra nguyên tử hơn, ít hơn một chút bằng cách sử dụng Parsernhư một người trợ giúp. Kết quả cuối cùng: Nhiều thử nghiệm hơn, phạm vi bảo hiểm nhiều hơn, nhiều góc và các trường hợp thú vị khác, mã tốt hơn và đảm bảo chất lượng cao hơn.


2
Điều này là hợp lý - đặc biệt liên quan đến thực tế là mọi thứ phụ thuộc vào nhiều người khác. Một bài kiểm tra đơn vị tốt nên kiểm tra tối thiểu có thể. Bất cứ điều gì trong phạm vi tối thiểu có thể nên được kiểm tra bằng thử nghiệm đơn vị tiến hành. Nếu bạn đã hoàn toàn kiểm tra Trình phân tích cú pháp, bạn có thể cho rằng bạn có thể sử dụng Trình phân tích cú pháp một cách an toàn để kiểm tra ParseStatement
Jon Story

6
Mối quan tâm thuần túy chính (tôi nghĩ) là để tránh viết phụ thuộc vòng tròn trong các bài kiểm tra đơn vị của bạn. Nếu kiểm tra trình phân tích cú pháp hoặc trình phân tích cú pháp sử dụng trình mở rộng và kiểm tra mở rộng này phụ thuộc vào trình phân tích cú pháp hoạt động, thì bạn có một rủi ro khó quản lý rằng tất cả những gì bạn đang kiểm tra là trình phân tích cú pháp và trình mở rộng đều nhất quán , trong khi đó bạn muốn làm là kiểm tra xem bộ mở rộng thực sự làm những gì nó phải làm . Nhưng miễn là không có sự phụ thuộc ngược lại, sử dụng trình phân tích cú pháp trong bài kiểm tra đơn vị này thực sự không khác biệt gì so với việc sử dụng thư viện chuẩn trong bài kiểm tra đơn vị.
Steve Jessop

@SteveJessop Điểm tốt. Điều quan trọng là sử dụng các thành phần độc lập .
Jonathan Eunice

3
Một cái gì đó tôi đã thực hiện trong trường hợp bản thân trình phân tích cú pháp là một hoạt động đắt tiền (ví dụ: đọc dữ liệu từ các tệp Excel qua com interop) là để viết các phương thức tạo thử nghiệm chạy trình phân tích cú pháp và mã đầu ra cho bàn điều khiển tạo lại cấu trúc dữ liệu mà trình phân tích cú pháp trả về . Sau đó tôi sao chép đầu ra từ máy phát vào các bài kiểm tra đơn vị thông thường hơn. Điều này cho phép giảm sự phụ thuộc chéo ở chỗ trình phân tích cú pháp chỉ cần hoạt động chính xác khi các bài kiểm tra được tạo không phải mỗi khi chúng chạy. (Không lãng phí một vài giây / thử nghiệm để tạo / hủy các quy trình Excel là một phần thưởng tuyệt vời.)
Dan Neely

+1 cho cách tiếp cận của @ DanNeely. Chúng tôi sử dụng một cái gì đó tương tự để lưu trữ một số phiên bản nối tiếp của mô hình dữ liệu của chúng tôi làm dữ liệu thử nghiệm, do đó chúng tôi có thể chắc chắn rằng mã mới vẫn có thể hoạt động với dữ liệu cũ hơn.
Chris Hayes

6

Tất nhiên là ổn rồi!

Bạn luôn cần kiểm tra chức năng / tích hợp thực hiện đường dẫn mã hoàn chỉnh. Và đường dẫn mã hoàn chỉnh trong trường hợp này có nghĩa là bao gồm cả việc đánh giá mã được tạo. Đó là bạn kiểm tra rằng phân tích cú pháp x = 2 + 3 * atạo ra mã mà nếu chạy với a = 5sẽ được đặt xthành 17và nếu chạy với a = -2sẽ được đặt xthành -4.

Bên dưới điều này, bạn nên thực hiện các bài kiểm tra đơn vị cho các bit nhỏ hơn miễn là nó thực sự giúp gỡ lỗi mã . Các bài kiểm tra chi tiết hơn bạn sẽ có, xác suất cao hơn rằng mọi thay đổi đối với mã cũng sẽ cần thay đổi bài kiểm tra, vì giao diện bên trong thay đổi. Kiểm tra như vậy có ít giá trị lâu dài và thêm công việc bảo trì. Vì vậy, có một điểm giảm lợi nhuận và bạn nên dừng lại trước nó.


4

Các bài kiểm tra đơn vị cho phép bạn xác định các mục cụ thể bị phá vỡ và vị trí trong mã mà chúng đã phá vỡ. Vì vậy, chúng tốt cho thử nghiệm hạt rất tốt. Kiểm tra đơn vị tốt sẽ giúp giảm thời gian gỡ lỗi.

Tuy nhiên, từ kinh nghiệm kiểm tra đơn vị của tôi hiếm khi đủ tốt để thực sự xác minh hoạt động chính xác. Vì vậy, kiểm tra tích hợp cũng hữu ích để xác minh chuỗi hoặc chuỗi hoạt động. Kiểm tra tích hợp giúp bạn có được một phần của cách thông qua kiểm tra chức năng. Như bạn đã chỉ ra, vì sự phức tạp của các thử nghiệm tích hợp, khó tìm thấy điểm cụ thể trong mã nơi thử nghiệm bị phá vỡ. Nó cũng có một chút giòn hơn ở những thất bại ở bất cứ đâu trong chuỗi sẽ khiến thử nghiệm thất bại. Tuy nhiên, bạn vẫn sẽ có chuỗi đó trong mã sản xuất, vì vậy việc kiểm tra chuỗi thực tế vẫn hữu ích.

Lý tưởng nhất là bạn có cả hai, nhưng với bất kỳ giá nào, thường có một bài kiểm tra tự động tốt hơn là không có bài kiểm tra nào.


0

Thực hiện nhiều thử nghiệm trên trình phân tích cú pháp và khi trình phân tích cú pháp vượt qua các thử nghiệm, hãy lưu các đầu ra đó vào một tệp để giả lập trình phân tích cú pháp và kiểm tra thành phần khác.

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.