2012-12-07 36 views
5

Tôi đã viết lớp truy cập của riêng mình vào một công cụ trò chơi. Có một GameLoop được gọi là mọi khung hình cho phép tôi xử lý mã của riêng mình. Tôi có thể làm những việc cụ thể và kiểm tra xem những điều này có xảy ra không. Theo cách rất cơ bản, nó có thể trông giống như thế này:Cách kiểm tra mã không đồng bộ

void cycle() 
{ 
    //set a specific value 
    Engine::setText("Hello World"); 

    //read the value 
    std::string text = Engine::getText(); 
} 

Tôi muốn kiểm tra xem lớp Engine có hoạt động không bằng cách viết kiểm tra tự động. Tôi có một số kinh nghiệm trong việc sử dụng khung Unittest Boost cho các bài kiểm tra so sánh đơn giản như thế này.

Vấn đề là, một số thứ tôi muốn động cơ thực hiện chỉ được xử lý sau khi gọi tới số cycle(). Vì vậy, hãy gọi số Engine::getText() trực tiếp sau Engine::setText(...) sẽ trả về một chuỗi trống. Nếu tôi đợi đến khi cuộc gọi tiếp theo của cycle() giá trị phù hợp sẽ được trả lại.

Tôi bây giờ tự hỏi làm thế nào tôi nên viết bài kiểm tra của tôi nếu nó không thể xử lý chúng trong cùng một chu kỳ. Có bất kỳ thực hành tốt nhất nào không? Có thể sử dụng phương pháp "thử nghiệm truyền thống" được đưa ra bởi khung Boost Unittest trong môi trường như vậy không? Có lẽ các khuôn khổ khác nhằm vào một trường hợp đặc biệt như vậy không?

Tôi đang sử dụng C++ cho mọi thứ ở đây, nhưng tôi có thể tưởng tượng rằng có câu trả lời không liên quan đến ngôn ngữ lập trình.

UPDATE: Không thể để truy cập Engine ngoài cycle()

+0

Trừ khi Động cơ có thể báo hiệu bạn theo cách xử lý xong, tôi không thực sự thấy việc này hoạt động. Rất tò mò để xem câu trả lời của người khác, mặc dù. –

Trả lời

-1

Có hai lựa chọn với bạn:

Nếu thư viện mà bạn có thể được sử dụng đồng bộ hoặc sử dụng C++ 11 tương lai như cơ sở (trong đó có thể chỉ ra readyness của kết quả) sau đó trong trường hợp thử nghiệm của bạn, bạn có thể làm điều gì đó như sau

void testcycle() 
{ 
    //set a specific value 
    Engine::setText("Hello World"); 
    while (!Engine::isResultReady()); 
    //read the value 
    assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT"); 
} 

Nếu bạn không có ở trên là tốt nhất bạn có thể làm có một thời gian chờ (đây không phải là một lựa chọn tốt bởi vì mặc dù bạn có thể có những thất bại giả mạo):

void testcycle() 
{ 
    //set a specific value 
    Engine::setText("Hello World"); 
    while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") { 
     wait(1 millisec); 
     if (total_wait_time > 1 sec) // you can put whatever max time 
       assert(0); 
    } 

} 
+0

Câu trả lời đầu tiên là không thể vì động cơ không có 'isResultReady()', câu trả lời thứ hai là xấu bởi thiết kế: giới thiệu thời gian chờ và ngủ trong loại thử nghiệm này là một điều xấu, bởi vì bạn quên rằng thời gian cần thiết để ngủ có thể khác nhau trên mọi máy. Core i7 của bạn có thể chỉ cần 1 giây, nhưng một số Pentium cũ hơn có thể cần 2. Trong cả hai trường hợp, testcase sẽ được truyền, nhưng - nếu một giấc ngủ được sử dụng - nó sẽ thất bại trong trường hợp thứ hai. –

+1

Quá trình GameEngine 'Engine :: setText (..)' sau khi gọi 'cycle()', do đó việc thêm thời gian chờ sẽ giống như nếu tôi gọi phương thức 'Engine :: getText()' ngay sau đó, nó chỉ mất nhiều thời gian hơn thời gian. Tôi chỉ có thể nhận được kết quả đúng sau khi 'setText' được xử lý trong GameEngine, có nghĩa là trong' cycle() ' – MOnsDaR

+0

@DanielKamilKozar - bạn nên đọc đúng bình luận của tôi .." (đây không phải là một lựa chọn tốt mặc dù bởi vì bạn có thể có lỗi giả mạo) " – RamneekHanda

0

Trong ví dụ của bạn ở trên, std::string text = Engine::getText(); là mã bạn muốn ghi nhớ từ một chu kỳ nhưng thực hiện trong kế tiếp. Bạn có thể lưu nó để thực hiện sau này. Ví dụ - bằng cách sử dụng C++ 11, bạn có thể sử dụng một lambda để bọc thử nghiệm vào một hàm đơn giản được chỉ định nội tuyến.

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