Một cách tự động tạo Test Data và JMeter script cho ứng dụng SOAP với Tomcat ServletFilter và Log4j

Hi Vtitans!
Lần trước viết một bài hơi nhiều chữ, mình xin bù lại bằng một bài code.
Vấn đề của lần này:

Làm sao tạo test case cho dự án migrate web service?

Vâng, migrate, và dự án migrate thì có nhiều khó khăn không tưởng lắm. Thường thì mọi thứ đều có số lượng lớn, tay phải to, các solution đều mong muốn phải "triển khai ngang" hàng loạt hoặc automate được.

Ôi mẹ ơi, có hàng nghìn cái method, (và hàng trăm cái bảng!!!)

Dự án migrate đồ cổ thì không thể có tài liệu như mong muốn được, chỉ có source code và team phải: 1) đọc nó 2) chạy được nó. Dự án này dùng Java 6, Tomcat 5, Seasar, Axis và mình hứa là lần sau sẽ không ngây thơ đi đọc file wsdl để bắt đầu "phân tích kĩ thuật" nữa. Cũng không thể chờ các senior dev tóm tắt 1000 method về 10 design pattern được, việc làm sao họ không thể mô tả hệ thống mà vẫn code được và đưa được dự án đến Go live là một bí quyết mà họ sẽ không bao giờ chia sẻ - hãy tôn trọng và tự hiểu.
Phương pháp thiết thực là, một khi tester đã chạy được hệ thống cũ, tìm cách capture test data để làm test case cho hệ thống mới (Còn làm sao chị em chạy được nó, cũng là bí quyết và mình rất khâm phục, vậy thôi).

Điểm các phương án capture data

Nếu client là web browser thì có thể dùng JMeter proxy để capture hàng loạt request, và kết hợp phân tích từ browser khi cần để hiểu và tinh chỉnh data. Nhưng phương án này loại vì client là desktop.
Phương án tiếp theo là dùng một tool như WireShark, do các dev cũng đang dùng tool này, tuy nhiên có nhiều câu hỏi đặt ra mà không ai biết, mình mù tịt nhưng nó không phải là HTTP proxy nên loại.
Phương án hứa hẹn nhất là dùng proxy phía server như nginx hay apache httpd. Mình chuẩn bị tìm hiểu cách này thì một bạn gợi ý cách khác, sau khi review mình thấy là phải code nhưng bù lại đáp ứng được mọi thứ mình muốn:

  • capture được theo cặp HTTP request/response
  • lấy được hoặc gán thêm data phục vụ merge, sort và filter như client IP, timestamp (cần thiết vì các request cần được nhóm lại theo function hay màn hình với đúng thứ tự của chúng, và nên loại được các request vô nghĩa do client refresh)
  • tool viết ra có thể dễ dàng cài đặt hoặc vô hiệu hoá trên server

Code - Dump data trên Tomcat

Vâng đến đây thì không có gì bí mật cả, cơ bản thì mình viết một cái Servlet Filter và cài đặt nó vào Tomcat. Khi có request gửi đến, Tomcat đưa cho mình, mình copy data và trả về nguyên vẹn, Tomcat đưa cho app xử lý, app viết response, mình lại được đọc response, copy và log ra file, rồi Tomcat trả cho client. Một vòng như thế gọi là một FilterChain, và nó được vẽ ở đây: https://stackoverflow.com/questions/25196867/how-filter-chain-invocation-works
Mình copy ảnh từ link trên nha:
undefined

Class của bạn cần implement javax.servlet.Filter và override hàm doFilter():

public class YourFilter implements Filter {
    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws ... {
        //get request and context data (request body + others like method, client ip, ...)
        //log to file
        //
        //by this line, you return the request to the chain and wait till it comes back
        arg2.doFilter(requestWrapper, responseWrapper);
        //
        //read response content, log to file
        //
    }
    //
}

Rất lưu ý là một khi bạn đã đọc request InputStream (in = request.getInputStream(); in.read()) thì filter class sau sẽ không còn gì để đọc nữa, nói cách khác app sẽ không nhận được data, nên bạn cần sử dụng một biện pháp clone InputStream. Trước đây mình dùng org.apache.commons.io.output.TeeOutputStream. Như bạn biết thì có thể có hàng tá vấn đề về version compat nên hãy tự search từ đầu cho code của bạn nhé, đây là một câu trả lời có vẻ mới: https://stackoverflow.com/questions/5923817/how-to-clone-an-inputstream
Và cuối cùng, có vẻ mình cũng phải loay hoay một hồi mới config được apache log4j và web.xml. Nhưng đó là do mình bị syndrome chứ bài này không có gì khó đối với bạn.
Note: bạn cần tìm hiểu data mẫu nhé, ví dụ dự định log dạng CSV thì cần biết data có thể có nhiều dòng không, hay có chứa delimiter không.

Code - Generate JMeter script

Sau khi có được file dump test data, bây giờ muốn làm gì thì làm thôi. Về lý thuyết bạn có thể viết tool gửi request đến 2 hệ thống cũ và mới, và compare kết quả nhận được nhằm phát hiện sai khác. Và dự án quả có làm thế thật, với kết quả cũng phát hiện được một số lỗi, nhưng không thể tính nó là một phương án test function hiệu quả, và khi hệ thống mới về cơ bản đã hoạt động, các tester có thể triển khai hết công lực thì tool này nhanh chóng nghỉ hưu.

Còn load test thì sao? Nếu biết script JMeter (.jmx) thực ra là xml thì bạn sẽ dễ dàng hình dung các công đoạn xử lý tiếp theo để build ra nó từ CSV. Đừng lạm dụng một ngôn ngữ xử lý XML nào cả, chỉ đơn giản là viết trước một test script làm template, rồi dùng shell script đọc CSV và add các request vào thôi.
Đến đây mình nhớ là một developer đã ngồi rà soát và tinh chỉnh data - có một khâu khó khăn để làm cho recorded data trở thành valid data khi replay, và phải gửi data thế nào thì mới đi được vào đoạn code nào? Không có công sức và hiểu biết của developer này - tích luỹ được nhờ tận hiến - thì ba cái mớ code mình viết không có ích gì. Vì vậy, mình không code nữa và dùng lời kết để tưởng nhớ tới người em hahaha ^^

Thân, from Châu D9
P/S: Hi vọng nải chuối của mình tuy còn xanh nhưng cũng cho vài gợi ý, và nếu bạn có kinh nghiệm thì hãy chia sẻ ý tưởng giúp anh em migrate dễ dàng hơn nhé!

Leave a Reply

Your email address will not be published. Required fields are marked *