2012-03-05 29 views
9

Tôi đang viết trình biên dịch Tiger trong C# và tôi sẽ dịch mã số Tiger thành IL.Kiểm tra đơn vị viết trong trình biên dịch của tôi (tạo IL)

Trong khi thực hiện kiểm tra ngữ nghĩa của mọi nút trong AST của tôi, tôi đã tạo nhiều thử nghiệm đơn vị cho việc này. Đó là khá đơn giản, bởi vì phương pháp CheckSemantic của tôi trông như thế này:

public override void CheckSemantics(Scope scope, IList<Error> errors) { 
... 
} 

như vậy, nếu tôi muốn viết một số bài kiểm tra đơn vị cho việc kiểm tra ngữ nghĩa của một số nút, tất cả tôi phải làm là xây dựng một AST, và cuộc gọi phương pháp đó. Sau đó, tôi có thể làm điều gì đó như:

Assert.That(errors.Count == 0); 

hoặc

Assert.That(errors.Count == 1); 
Assert.That(errors[0] is UnexpectedTypeError); 
Assert.That(scope.ExistsType("some_declared_type")); 

nhưng tôi bắt đầu thế hệ mã trong thời điểm này, và tôi không biết những gì có thể là một thói quen tốt khi viết unit tests cho giai đoạn đó.

Tôi đang sử dụng lớp ILGenerator. Tôi đã nghĩ về những điều sau đây:

  • Tạo mã của chương trình mẫu Tôi muốn thử nghiệm
  • Save rằng thực thi
  • Execute tập tin đó, và lưu trữ kết quả trong một file
  • Khẳng định chống lại tệp đó

nhưng tôi tự hỏi liệu có cách nào tốt hơn để làm điều đó không?

Trả lời

14

Đó chính xác là những gì chúng tôi làm trong nhóm trình biên dịch C# để kiểm tra trình tạo IL của chúng tôi.

Chúng tôi cũng chạy tệp thi hành được tạo thông qua ILDASM và xác minh rằng IL được tạo như mong đợi và chạy nó qua PEVERIFY để đảm bảo rằng chúng tôi đang tạo mã có thể kiểm chứng. (Trừ tất nhiên trong những trường hợp chúng ta đang cố tình tạo mã chưa được kiểm chứng.)

+0

Bạn nên biết điều đó. Tôi sẽ làm theo cách đó. Tôi chỉ là một chút lo lắng về hiệu suất của nhiều thử nghiệm đang chạy, và tạo, đọc và xóa (các) tệp trên đĩa. –

+3

@OscarMederos: Nếu hiệu suất không đủ tốt thì (1) làm profiling để tìm ra cái gì là chậm và sửa nó nếu bạn có thể, hoặc (2) thay đổi chiến lược kiểm tra của bạn để một số thử nghiệm chạy trên mọi checkin, một số test chạy qua đêm, và một số chạy vào cuối tuần. Bằng cách đó, bạn sẽ có được sự cân bằng tốt trong việc phát hiện nhanh các vấn đề và vẫn đang thực hiện kiểm tra kỹ lưỡng. –

0

Bạn có thể nghĩ ra thử nghiệm như làm hai điều:

  1. cho bạn biết nếu đầu ra đã thay đổi
  2. cho bạn biết nếu đầu ra không chính xác

Xác định xem điều gì đó có thay đổi thường nhanh hơn đáng kể so với xác định xem có điều gì không chính xác hay không, vì vậy có thể là chiến lược tốt để chạy kiểm tra phát hiện thường xuyên hơn phát hiện sai kiểm tra.

Trong trường hợp của bạn, bạn không cần phải chạy tệp thi hành do trình biên dịch tạo ra mỗi khi bạn có thể nhanh chóng xác định rằng tệp thực thi không thay đổi vì bản sao đã biết (hoặc giả định) tốt của cùng một tệp thực thi được tạo. Bạn thường cần phải thực hiện một số thao tác nhỏ trên đầu ra mà bạn đang thử nghiệm để loại bỏ sự khác biệt được mong đợi (ví dụ: đặt ngày nhúng thành giá trị cố định), nhưng khi bạn đã thực hiện xong, hãy phát hiện thay đổi kiểm tra dễ viết vì xác nhận về cơ bản là so sánh tệp: Đầu ra có giống với đầu ra tốt được biết cuối cùng không? Có: Vượt qua, Không: Không.Vì vậy, vấn đề là nếu bạn thấy các vấn đề về hiệu suất khi chạy các tập tin thực thi do trình biên dịch của bạn tạo ra và phát hiện các thay đổi trong đầu ra của các chương trình đó, bạn có thể chọn chạy các kiểm tra phát hiện các thay đổi ở giai đoạn trước đó bằng cách so sánh các tệp thực thi. Quay lại đầu trang

1

Tôi đã tạo một post-compiler in C# và tôi đã sử dụng phương pháp này để kiểm tra CIL đột biến:

  1. Save the assembly trong một temp file, đó sẽ bị xóa sau khi tôi đang thực hiện với nó.
  2. Sử dụng PEVerify đến check the assembly; nếu có vấn đề tôi sao chép nó vào một nơi đã biết để phân tích lỗi thêm.
  3. Kiểm tra nội dung lắp ráp. Trong trường hợp của tôi, tôi chủ yếu là loading the assembly dynamically trong một AppDomain riêng biệt (vì vậy tôi có thể xé nó xuống sau) và thực hiện một class in there (vì vậy nó giống như một hội đồng tự kiểm tra: here's a sample implementation).

Tôi cũng đã đưa ra một số ý tưởng về cách phân tích thử nghiệm tích hợp trong this answer.

Các vấn đề liên quan