เมื่ออาทิตย์ก่อน application developer เจอปัญหา run unit test ไม่ผ่านใน .NET project แต่ว่า run ผ่านบนเครื่อง CI (it doesn’t work on my machine LOL) โดยเฉพาะกับ test case ที่เกี่ยวข้อง DateTime ซึ่ง ค่าปีที่จะมีค่าเพิ่มขึ้นมา 543 ปี

ตัวอย่างปัญหา

มาลองดูตัวอย่างการทดสอบที่เกี่ยวกับ DateTime ใน XUnit กันก่อน เช่น

เมื่อเรารันเทสต์ข้างต้นบนเครื่องที่ Locale เป็นไทย ค่าปีของ actual จะผิดไป 543 ปี

Assert.Equal() Failure
Expected: 2023-01-01T00:00:00.0000000
Actual:   1480-01-01T00:00:00.0000000

อาการแบบนี้มักจะเกิดจากเครื่องของเราตั้งค่า Locale เป็นภาษาไทย ซึ่งใช้ปีพุทธศักราชที่มากกว่าปีคริสต์ศักราช อยู่ 543 ปีนั่นเอง

วิธีแก้ไข

เพื่อให้แน่ใจว่า unit test ของเราใช้เวลาในรูปแบบสากล (หรือแบบ UTC) ที่ไม่มีผลกระทบจาก Locale หรือ ปีพุทธซักราช วิธีง่าย ๆ ที่ใช้แก้ปัญหานี้ได้คือเพิ่มการตั้งค่า <InvariantGlobalization> ในไฟล์ .csproj ของ project ที่ใช้ run unit test โดยตั้งค่าให้เป็น true เพื่อให้ .NET ไม่สนใจ Locale ของเครื่อง และใช้การตั้งค่ากลาง (Invariant Culture) แทน

จากนั้น ลอง run test อีกครั้ง จะพบว่า test ผ่านแล้ว เพราะการตั้งค่านี้ทำให้ DateTime ถูกจัดการโดยไม่มีการแปลงปีเป็นพุทธศักราช

นั่นหมายความว่าไม่ว่า test จะถูก run ที่ CI server ในต่างประเทศหรือเครื่องส่วนตัวในไทย DateTime จะถูกแสดงผลและเปรียบเทียบตามมาตรฐานเดียวกัน

มีอีกวิธีนึงคือใช้ CultureInfo.InvariantCulture ร่วมด้วยใน code ที่มีการแปลงเป็น DateTime

การใช้ CultureInfo.InvariantCulture จะช่วยให้มั่นใจได้ว่า code จะทำงานได้ถูกต้องโดยไม่มีการเปลี่ยนแปลงตาม Locale ของเครื่องนั่นเอง

หวังว่าวิธีแก้นี้จะช่วยให้ test ของเรามีความสม่ำเสมอไม่ว่าเราจะ run ที่ไหน