Lưu trữ

Archive for Tháng Tám, 2010

Ví dụ về Test-Driven Development

Tháng Tám 29, 2010 Để lại phản hồi

Đây là một số ví dụ về Test-Driven Development mà mình đã tập hợp được.

Ngắn:

  • Chapter 6 – Agile principles, patterns, and practices in C# – by Martin C. Robert, Martin Micah. Khá thú vị. Xem online tại đây.
  • Phần 3, 4, 5 của Craftsman.

Trung bình:

  • Part I – Test-Driven Development by example – Kent Beck.
  • Part III – Test-Driven Development: A practical guide – David Astels.
  • Phần 6, 7, 8, 9, 10 của Craftsman.

Dài:

  • Part II – Test-Driven Development in Microsoft .NET – James W. Newkirk, Alexei A. Vorontsov.
  • Part III – Growing object-oriented software, guided by test – Steve Freeman, Nat Pryce.

Đặc biệt, nếu bạn có thời gian, không thể bỏ qua bộ Craftsman.

Thẻ:

Đọc tài liệu tiếng Anh

Tháng Tám 23, 2010 Để lại phản hồi

HM viết bài này bởi vì có nhiều từ khóa tìm kiếm bằng tiếng Việt vào blog này quá, và hầu hết là về các vấn đề đơn giản, và ít bám theo liên kết trong blog để đến các bài viết tiếng Anh chi tiết hơn. Đây là một việc rất không tốt, bởi vì là lập trình viên thì càng cần phải biết dùng tiếng Anh để đọc và tra cứu tài liệu.

Trước hết phải dạo qua bước thủ tục đã. Tại sao lập trình viên nên dùng tài liệu tiếng Anh (chứ không phải là tiếng Việt)?

  • Sách tiếng Anh (tất nhiên là những quyển hay nhất) có chất lượng tốt hơn sách tiếng Việt. Nói chính xác hơn, sách lập trình tiếng Việt đa phần rất tệ (và rất mỏng), chỉ lướt qua các kiến thức bề mặt chứ ít khi đi sâu vào cốt lõi của vấn đề. Ngoại lệ có lẽ là các sách dịch.
  • Phần lớn các công nghệ phổ biến đều được phát triển bởi các công ti Mĩ. Tài liệu hỗ trợ vì thế sẽ viết bằng tiếng Anh là chủ yếu. Nếu có dịch sang tiếng khác thì cũng còn lâu tiếng Việt mới tới lượt.
  • Stack Overflow. Đây là trang web hỏi đáp nổi tiếng nhất cho lập trình viên. Ngay cả những vấn đề chưa được tài liệu hóa thì bạn cũng có cơ hội tìm được câu trả lời ở đây. Thậm chí cỗ máy tìm kiếm của MSDN cũng lấy các kết quả từ Stack Overflow. Tiếng Anh là ngôn ngữ duy nhất được dùng trên trang này.
  • Sách điện tử tiếng Anh rất dễ kiếm, đủ đề tài từ lập trình đến dạy hẹn hò :D (tất nhiên, tải sách điện tử “lậu” là không hợp pháp).

Vậy làm sao để đọc tài liệu tiếng Anh? Thứ nhất là phải học tiếng Anh. Nếu học nghiêm túc thì chắc bằng A là đủ rồi. Thứ hai, phải luyện tập. Bạn cần phải:

  • Bớt thời gian tìm kiếm sách học tiếng Anh, rồi lời khuyên học tiếng Anh, v.v đi. Chỉ có luyện tập mới tạo nên sự hoàn thiện.
  • Tập đọc tài liệu. Tất nhiên HM không thể có dẫn chứng xác thực, nhưng có rất nhiều sinh viên mắc bệnh lười đọc, hiếm khi đọc trọn vẹn giáo trình cho môn học, mà chỉ phụ thuộc vào bài giảng của giáo viên. Nếu thi trắc nghiệm thì có khi chỉ cần giải đề năm trước và học thuộc là đã có thể qua (và qua với điểm khá) :D . Chỉ nhìn cái gì nhiều chữ đã nản thì còn tính gì đến tiếng Anh tiếng Việt, hơn nữa tài liệu tiếng Anh lúc nào cũng dài, chi tiết, dày đặc chữ. Tập càng sớm càng tốt, ngay từ môn học đầu tiên. Đừng sợ hãi những bài báo 8-9 trang, hay những quyển sách dày 400-500 trang, nếu nội dung của nó thật sự có ích. Đừng trông chờ một ai đó (kể cả Google) lúc nào cũng có thể trả lời cho bạn những câu hỏi kiểu như làm sao hiện thực thuật toán tìm đường ngắn nhất, thuật toán Euclid mở rộng là gì. Đừng phụ thuộc vào những bài giảng trên lớp. Hãy đọc sách và động não.
  • Đừng sợ tiếng Anh. Bạn sẽ không bao giờ đọc tốt tiếng Anh nếu bạn không đủ kiên nhẫn và quyết tâm đọc nó. Nhiều người mặc dù đã được học tiếng Anh khá bài bản nhưng vấn có tâm lí này. Chỉ cần cấu trúc của câu phức tạp một chút, chỉ cần đoạn văn dài một chút, là họ đã bỏ qua rồi. Đừng làm thế. Hãy kiên nhẫn đọc cho hiểu từ những câu thông báo ngắn trên màn hình đến những bài báo dài từ Wikipedia tiếng Anh. Cố gắng đừng đóng lại một trang web chỉ vì nó viết bằng tiếng Anh, hãy đóng nó chỉ khi nó không hữu ích.
  • Đọc tiếng Anh thật nhiều. Bạn có tin là thậm chí một quyển sách tiếng Anh cấp hai cũng giúp bạn cải thiện khả năng đọc tiếng Anh không? Khi đọc một câu tiếng Anh, đừng dịch nó qua tiếng Việt rồi mới hiểu nó, mà hãy cố gắng hiểu trực tiếp bằng tiếng Anh. Coi như những từ tiếng Anh đó chẳng qua là từ tiếng Việt. Chẳng hạn, apple là táo. Vậy táo là gì? Nếu bạn không định nghĩa được táo là gì, mà chỉ nghĩ táo là táo, thì cũng hãy nghĩ apple là apple thôi.
  • Đừng đọc cà nhắc. Tập trung vào cấu trúc của câu, xem câu đó nói gì, hơn là tập trung vào nghĩa của từng từ. Nếu nghĩa của từ đó không cần thiết cho việc hiểu cả câu thì lơ nó đi cũng được, khi gặp nhiều lần hãy tra. Nếu bạn phải dừng lại tra từ quá nhiều, bạn sẽ không tóm gọn được ý nghĩa của cả đoạn, và hơn nữa bạn cũng sẽ chóng chán đọc tiếng Anh.
  • Đừng xấu hổ. Nếu bạn chưa thạo thì bạn đọc chậm. Nếu không hiểu thì nói là không hiểu. Nhất là lúc đầu khi tập đọc tiếng Anh mà không dịch trung gian qua tiếng Việt mọi thứ sẽ rất khó khăn và mất nhiều thời gian. Cũng giống như tập gõ bàn phím mười ngón vậy, lúc đầu chắc chắn người tập sẽ gõ chậm hơn gõ “mổ cò”, nhưng sau cùng họ sẽ gõ nhanh hơn hẳn những người “mổ cò” (cộng với việc không cần nhìn bàn phím).
  • Đừng dừng lại. Ngay cả khi bạn đọc tiếng Anh như tiếng Việt, thì cũng không có nghĩa là bạn có thể dừng lại. Hãy đọc thêm tiếng Anh ở nhiều lĩnh vực khác, mở rộng vốn từ của mình, tập viết tiếng Anh nhiều hơn để tăng cường trình độ tiếng Anh của mình. Tại sao? HM không thể trả lời được, nhưng HM nghĩ sự tự mãn, dù nhỏ hay lớn, khi đã xuất hiện sẽ làm con người ta tiêu tan ý chí phấn đấu, trở nên sợ hãi và dừng bước trước những thử thách vượt quá khả năng.

Một số công cụ rất hữu ích:

  • Simple English Wikipedia. Wikipedia phiên bản chỉ dùng tiếng Anh đơn giản. Vì là Wikipedia chắc chắn sẽ có chủ đề thú vị với bạn.
  • Englishforums.com. Ở đây lúc nào cũng có giáo viên hoặc người bản xứ trả lời câu hỏi của bạn.
  • Lingoes. Từ điển, giống Babylon, nhưng miễn phí.

Mong là một ngày nào đó blog này sẽ không còn lượt truy cập nào nữa :D .

Thẻ:

SLF4J và logback

Tháng Tám 21, 2010 Để lại phản hồi

Mặc dù unit test có thể giúp hạn chế lỗi khi phát triển phần mềm, với những chương trình phức tạp, sự cố là không thể tránh khỏi, nghĩa là vẫn phải có debug. Và việc này sẽ đơn giản hơn rất nhiều nếu trạng thái của chương trình tại các thời điểm khác nhau được ghi lại. Ngoài ra, các thông tin này có thể giúp cải tiến chương trình về giao diện sử dụng, tốc độ, v.v. Đó là lí do chúng ta có các logging framework.

Tại sao không dùng println cho việc logging? Bởi vì chúng quá thô sơ. Một giải pháp logging, có lẽ phải đáp ứng các yêu cầu sau:

  • Tùy biến:
    • Bật, tắt logging (toàn bộ hoặc theo loại thông điệp.
    • Vị trí xuất log (màn hình, tập tin, database, v.v)
    • Định dạng, lượng thông tin cần log
  • Thông tin có thể log:
    • Vị trí gọi log
    • Thời gian
    • Thông điệp, stack trace, v.v

Có nhiều logging framework trong Java, trong đó nổi tiếng nhất là Log4J. Để thuận tiện khi chuyển đổi giữa các logging framework, người ta phát triển facade chung cho chúng. Không may là cũng lại có hơn một facade :) (Java là thế). Hiện nay, các dự án có vẻ đang ưa chuộng facade SLF4J. API của SLF4J được framework logback hiện thực trực tiếp (native implementation). Ngoài tính dễ sử dụng, SLF4J còn có một lợi thế là được phát triển bởi tác giả của Log4J—tất nhiên là người hiểu rõ các hạn chế của Log4J.

Dưới đây là một ví dụ nhỏ về SLF4J. Tài liệu hướng dẫn và cả javadoc của SLF4J và logback đã rất cụ thể và đầy đủ, nên nếu bạn muốn tìm hiểu sâu hơn thì đó là nơi tốt nhất để bắt đầu.

Mặc định của logback là log ra console:

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
public class HelloWorld { 
  public static void main(String[] args) { 
    Logger logger = LoggerFactory.getLogger("HelloWorld"); 
    logger.debug("Hello world."); 
  } 
}

Kết quả (console):

22:12:35.261 [main] DEBUG HelloWorld - Hello world.

Sửa đổi tập tin cấu hình (thường là logback.xml) và ta sẽ log được ra tập tin:

<configuration> 
  <appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>hw.log</file> 
    <encoder> 
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> 
    </encoder> 
  </appender> 
  <root level="debug"> 
    <appender-ref ref="FILE" /> 
  </root> 
</configuration>

Kết quả (trong tập tin hw.log):

2010-08-21 21:35:57,583 DEBUG [main] HelloWorld [HelloWorld.java:7] Hello world.

Thẻ:,

JUnit

Tháng Tám 19, 2010 2 comments

Có lẽ đa số sinh viên chúng ta đều quen với việc hoàn tất chương trình, chạy thử, thấy sai, tìm và sửa lỗi, chạy thử, v.v. Điều này không có gì là sai trái, tuy nhiên nếu đợi đến khi hoàn tất chương trình rồi mới chạy thử, thì việc tìm và sửa lỗi sẽ tương đối vất vả. Quá trình này sẽ đơn giản hơn, nếu bạn có thể chia chương trình thành từng phần nhỏ, và test chúng một cách riêng rẽ. Đó là ý nghĩa của unit test.

Tuy nhiên, để unit test hiệu quả, chúng ta cần có các công cụ để tiến hành nó một cách tự động. Các công cụ này gọi là unit test framework. Với Java, framework nổi tiếng nhất là JUnit.

Nếu bạn muốn tìm hiểu về JUnit, thì bạn nên đọc “JUnit in action”. Dưới đây là một ví dụ nhỏ về JUnit để bạn tham khảo.

Kiểm tra với một test case

Giả sử chúng ta có một class Number như dưới đây. Mỗi object của class đại diện cho một số nguyên. Method isEven kiểm tra tính chẵn lẻ của số nguyên đó. Mục tiêu của chúng ta là kiểm tra tính đúng đắn của method isEvent.

public class Number { 
    private int number; 
    public Number(int number) { this.number = number; } 
    public boolean isEven() { return (number % 2 == 0)?true:false; } 
}

Việc đầu tiên là tải tập tin junit-4.x.x.jar và cho nó vào CLASSPATH. Đoạn mã dưới đây sẽ kiểm tra isEvent với 2.

import static org.junit.Assert.*; 
import org.junit.Test; 
public class NumberTest { 
    @Test public void testIsEven() { 
        Number number = new Number(2); 
        assertTrue(number.isEven()); 
    } 
}

Dịch hai đoạn mã trên và chạy lệnh java org.junit.runner.JUnitCore NumberTest. Khi đó JUnit sẽ chạy các method được đánh dấu @Test. Kết quả là:

JUnit version 4.8.2 
. 
Time: 0.008 
OK (1 test)

Kiểm tra với nhiều test case

Bây giờ ta muốn kiếm tra với nhiều số hơn. Chúng ta sẽ không chèn thêm assertTrue vào testIsEven (vì như vậy sẽ không thể biết được số nào làm cho test bị sai). Thay vào đó, chúng ta sẽ tham số hóa method testIsEven. Các tham số được lấy từ bộ test tạo ra bởi method getTestParameters.

import static org.junit.Assert.*; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.junit.runners.Parameterized; 
import org.junit.runners.Parameterized.Parameters; 
import java.util.Arrays; 
import java.util.Collection;  

@RunWith(value=Parameterized.class) 
public class NumberParameterizedTest { 
    private int value; 
    private boolean expected; 
    public NumberParameterizedTest(int value, boolean expected) { 
        this.value = value; 
        this.expected = expected; 
    } 
    @Parameters public static Collection&lt;Object[]&gt; getTestParameters() { 
        return Arrays.asList(new Object[][] { {2, true}, {3, false}, {5, true}, }); 
    } 
    @Test public void testIsEven() { 
        Number number = new Number(value); 
        assertEquals(number.isEven(), expected); 
    } 
}

Lần này, Junit sẽ lần lượt lấy từng mẫu ra để kiểm tra. Kết quả là (trích):

JUnit version 4.8.2 
...E 
Time: 0.022 
There was 1 failure: 
1) testIsEven[2](NumberParameterizedTest)...

Như vậy là test sai với mẫu thứ ba (5, true) (vì đếm từ 0).

Kiểm tra Exception

Trong một số trường hợp, một method sẽ throw Exception thay vì trả về kết quả tính toán. Để đảm bảo hành vi của method đúng như mong đợi, chúng ta phải test cả những trường hợp này để xem chúng có throw đúng Exception cần throw không. @Test(expected=YourException.class) là annotation phục vụ cho mục đích này.

Dùng test làm hướng dẫn sử dụng

Hãy nhìn lại đoạn code trên. Khi đọc test (nếu bạn hiểu JUnit), bạn sẽ suy ra ngay cách sử dụng method isEven: đầu tiên tạo một object Number với constructor nhận vào giá trị int, sau đó gọi isEven(). Vậy là, test code còn một tác dụng khác là làm hướng dẫn sử dụng (tương tự như các đoạn code trong tutorial trên mạng). Ưu điểm của việc lấy test làm hướng dẫn sử dụng là nhanh gọn và bám sát theo thay đổi của chương trình.

Follow

Get every new post delivered to your Inbox.