মডিউল পাঠ (2/5)
টেবিল চালিত পরীক্ষা
টেবিল-চালিত পরীক্ষা হল Go-এর ইডিওম্যাটিক প্যাটার্ন: N আলাদা TestThisSpecificCase ফাংশন লেখার পরিবর্তে, আপনি কেসগুলির একটি স্লাইস ঘোষণা করুন এবং পুনরাবৃত্তি করুন। একটি দাবী ব্লক আছে, এবং পরীক্ষার ডেটা যুক্তি থেকে আলাদা করা হয়েছে।
বেস প্যাটার্ন
func TestAbs(t *testing.T) {
cases := []struct {
name string
in int
want int
}{
{"pos", 3, 3},
{"neg", -3, 3},
{"zero", 0, 0},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := Abs(tc.in); got != tc.want {
t.Errorf("Abs(%d) = %d; voglio %d", tc.in, got, tc.want)
}
})
}
}তিনটি উপাদান:
- অনামী কাঠামোর স্লাইস স্বাভাবিক ক্ষেত্রগুলির সাথে:
name, ইনপুট, প্রত্যাশিত আউটপুট (এবং সম্ভবত একটি প্রত্যাশিত ত্রুটি)। for _, tc := range cases— এক্সিকিউশন লুপ।t.Run(tc.name, func(t *testing.T) { ... })— প্রতিটি কেস তার নিজের নামের সাথে একটি সাব-টেস্ট হয়ে যায়।
কেন t.Run?
t.Run একটি উপ-পরীক্ষা তৈরি করে যাতে আছে:
- ব্যক্তিগত নাম আউটপুটে দেখানো হয়েছে:
TestAbs/pos,TestAbs/neg, ... - এর নিজস্ব
t *testing.T: একটি ক্ষেত্রে ব্যর্থতা অন্যকে থামায় না (যদি নাt.Fatalব্যবহার করা হয়)। - কমান্ড-লাইন ফিল্টারিং:
go test -run TestAbs/negশুধুমাত্র সেই ক্ষেত্রেই চলে। - ঐচ্ছিক সমান্তরালতা: সমান্তরাল করতে ফাঙ্কের ভিতরে
t.Parallel()এ কল করুন।
go test -v -run TestAbs/negপ্রত্যাশিত ত্রুটি সহ ক্ষেত্রে
cases := []struct {
name string
in string
want int
wantErr bool
}{
{"ok", "42", 42, false},
{"bad", "x", 0, true},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got, err := Atoi(tc.in)
if (err != nil) != tc.wantErr {
t.Fatalf("err = %v, wantErr = %v", err, tc.wantErr)
}
if !tc.wantErr && got != tc.want {
t.Errorf("got %d, want %d", got, tc.want)
}
})
}লুপ ক্লোজার পিটফল (প্রি-গো 1.22)
Go 1.22-এর আগে সংস্করণে, tc ভেরিয়েবলটি পুনরাবৃত্তি জুড়ে ভাগ করা হয়েছে: t.Parallel()-কে t.Run-এর ভিতরে কল করার ফলে সমস্ত উপ-পরীক্ষা একই শেষ কেসের বিরুদ্ধে চালানো হয়েছে। সমাধান ছিল:
for _, tc := range cases {
tc := tc // local rebind (pre-1.22)
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
// ...
})
}মামলাগুলোর নামকরণ
সর্বোত্তম অনুশীলন:
- একটি সংক্ষিপ্ত কিন্তু উদ্দীপক নাম:
"empty input","too large","negative"। - যদি আপনি
-runদিয়ে সহজে ফিল্টার করতে চান (অথবা আন্ডারস্কোর ব্যবহার করুন) কোনো স্পেস নেই। - সর্বদা একটি "হ্যাপি পাথ" কেস, একটি "এজ" কেস (শূন্য, খালি) এবং অন্তত একটি ত্রুটি কেস অন্তর্ভুক্ত করুন।
ব্যায়াম
Abs (পজিটিভ, নেগেটিভ, শূন্য) পরীক্ষা করার জন্য 3টি কেস দিয়ে পপুলেট ইন এবং ওয়ান্ট ফিল্ড সহ বেনামী স্ট্রাকটের একটি কেস স্লাইস সংজ্ঞায়িত করুন।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
প্রতিটি কেসকে একটি নামযুক্ত সাব-টেস্টে পরিণত করতে tc.name দিয়ে t.Run যোগ করুন।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
এন পৃথক টেস্ট ফাংশনের তুলনায় টেবিল-চালিত প্যাটার্নের প্রধান সুবিধা কী?
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { ... })
}