مشخصات مقاله
-
1722
-
0.0
-
3082
-
0
-
0
استفاده از فریم ورک Hamcrest جهت اجرای تست نرم افزاری
هدف از Hamcrest matcher framework
Hamcrest یک فریم ورک و مجموعه ای از کتابخانه های اجرای تست های نرم افزاری هست. فریم ورک مزبور به شما این امکان را می دهد تا به واسطه ی کلاس های matcher از پیش موجود، شرایط خاصی را بررسی کرده و از صحت آن ها اطمینان حاصل نمایید. علاوه بر آن، شما می توانید matcher های خود را با پیاده سازی اختصاصی تعبیه نمایید.
Hamcrest نسل سوم از فریم ورک matcher هست. اولین نسل از این فریم ورک از assert(logical statement) استفاده می کرد که کاستی قابل توجه آن عدم خوانایی بالا بود. نسل دوم توابع خاصی برای assertion و انتظار دریافت خروجی مورد نظر همچون assertEquals() ارائه دادند. این رویکرد سبب اضافه شدن توابع assert متعدد دیگری به Hamcrest که نسل سوم از این فریم ورک می باشد، شد. Hamcrest از متدی به نام assertThat و یک عبارت matcher برای بررسی اینکه تست موفق آمیز بود یا خیر استفاده می کند.
Hamcrest سعی دارد تا تست ها را تا حد امکان خوانا، مختصر و کاربر پسند تعبیه نماید. به طور مثال، متد is یک تابع میزبان یا wrapper برای equalTo(value) می باشد.
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.equalTo; boolean a; boolean b; // all statements test the same assertThat(a, equalTo(b)); assertThat(a, is(equalTo(b))); assertThat(a, is(b));
تکه کدهای زیر دستورات assert خالص JUnit4 را با matcher های Hamcrest مقایسه می کنند.
// JUnit 4 for equals check assertEquals(expected, actual); // Hamcrest for equals check assertThat(actual, is(equalTo(expected))); // JUnit 4 for not equals check assertFalse(expected.equals(actual)); // Hamcrest for not equals check assertThat(actual, is(not(equalTo(expected))));
می توانید matcher ها را با استفاده از anyof یا allof به صورت زنجیره ای و پشت سرهم فراخوانی نمایید.
assertThat("test", anyOf(is("testing"), containsString("est")));
در کل، پیغام های خطایی که Hamcrest تولید می کند، بسیار خوانا می باشند. علاوه بر آن در استفاده از Hamcrest، ویژگی type safety زبان جاوا به خوبی رعایت شده و matcher ها که از انواع داده ای generic استفاده می کنند دیگر با مشکل بر نخواهند خورد (کد type-safe اجازه ی دسترسی به بخش های نامربوط حافظه را نمی دهد. به عبارت دیگر تنها به آن بخش هایی از حافظه که امکان پذیر است اجازه ی دسترسی را می دهد).
استفاده از matcher ها در Hamcrest
اعلان dependency های مربوطه برای Gradle
جهت استفاده از Hamcrest matcher ها در پروژه ای که برای کامپایل از سیستم Gradle استفاده می کند، کافی است کتابخانه / dependency های زیر را به آن اضافه نمایید.
dependencies {
// Unit testing dependencies
testCompile 'junit:junit:4.12'
// Set this dependency if you want to use Hamcrest matching
testCompile 'org.hamcrest:hamcrest-library:1.3'
}
اعلان dependency های لازم برای سیستم Maven
<جهت استفاده از Hamcrest در پروژه ای که برای کامپایل از سیستم Maven استفاده می کند، لازم است dependency زیر را به فایل pom خود اضافه نمایید.
org.hamcrest hamcrest-library 1.3 test
اضافه کردن Hamcrest به طور مستقیم به classpath پروژه در محیط کاری Eclipse
ویرایشی از JUnit که در محیط برنامه نویسی Eclipse نصب می شود، صرفا matcher های اصلی Hamcrest را شامل می شود. جهت استفاده از تمامی matcher های موجود، آخرین نسخه ی hamcrest-all-*.jar را از آدرس https://code.google.com/p/hamcrest/downloads/list دنلود نمایید و سپس آن را به classpath پروژه ی خود اضافه کنید.
در صورت برخورد با خطای "java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package",، اطمینان حاصل نمایید که فایل hamcrest jar قبل از کتابخانه ی Junit در build path قرار گرفته است. جهت ویرایش ترتیب قرارگیری می توانید به بخش project properties در محیط کاری Eclipse تحت آدرس Java Build Path در تب Order and Export مراجعه نمایید.
استفاده کاربردی از Hamcrest
مثالکاربرد عملی از matcher های Hamcrest در کد زیر به نمایش گذاشته شده است.
assertThat(Long.valueOf(1), instanceOf(Integer.class));
استفاده از matcher های Hamcrest برای list ها
استفاده از matcher های Hamcrest برای نوع داده ای list در تکه کد زیر به نمایش گذاشته شده است.
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.core.Every.everyItem;
public class HamcrestListMatcherExamples {
@Test
public void listShouldInitiallyBeEmpty() {
List list = Arrays.asList(5, 2, 4);
assertThat(list, hasSize(3));
// ensure the order is correct
assertThat(list, contains(5, 2, 4));
assertThat(list, containsInAnyOrder(2, 4, 5));
assertThat(list, everyItem(greaterThan(1)));
}
}
// Check that a list of objects has a property race and
// that the value is not ORC
assertThat(fellowship, everyItem(hasProperty("race", is(not((ORC))))));
مرور کلی بر matcher های Hamcrest
مهم ترین matcher های فریم ورک مزبور در زیر شرح داده شده اند:
- allof – چنانچه تمامی matcher ها با یکدیگر مطابقت داشته باشند، همخوانی رخ می دهد.
- anyof – چنانچه هر کدام از matcher ها مطابقت داشته باشد، همخوانی رخ می دهد.
- not – در صورتی که matcher گنجانده شده در wrapper مطابقت نداشته باشد و بالعکس، همخوانی رخ می دهد.
- equalTo – با استفاده از متد equals بررسی می کند آیا آبجکت ها با هم برابر هستند یا خیر.
- is – یک پیشوند برای equalTo است که صرفا جهت بهبود خوانایی کد به این متد اضافه می شود.
- hasToString - Object.toString را تست می کند.
- instanceOf، isCompatibleType – نوع را تست می کند.
- notNullValue، nullValue – بررسی می کند آیا مقدار null است یا خیر.
- sameInstance – هویت آبجکت را بررسی می کند. در واقع بررسی می کند آیا این آبجکت از همان نمونه است یا خیر.
- hasEntry، hasKey، hasValue – بررسی می کند آیا نوع داده ای map آیتمی داخل خود دارد یا خیر.
- hasItem، hasItems – بررسی می کند آیا یک collection داخل خود آیتم هایی را دارد یا تهی است.
- hasItemInArray – بررسی می کند آیا یک آرایه تهی است یا حاوی آیتم و مقداری می باشد.
- closeTo – بررسی می کند آیا مقادیر ممیز شناور نزدیک به مقدار مورد نظر هستند یا خیر.
- greaterThan، greaterThanOrEqualTo، lessThan، lessThanOrEqualTo
- equalToIgnoringWhiteSpace – بررسی می کند آیا رشته ها با هم برابر هستند یا خیر. لازم به ذکر است که در تست فضای خالی نادیده گرفته می شود.
- containsString، endsWith، startsWith – بررسی می کند آیا رشته ها با هم مطابقت دارند یا خیر.
ساخت Hamcrest matcher اختصاصی خود
توسعه دهنده می تواند اعضای کلاسی به نام TypeSafeMatcher را به ارث برده (extend) و بدین وسیله Hamcrest matcher اختصاصی خود را بنویسد. مثال زیر یک نمونه از پیاده سازی matcher را نمایش می دهد که وظیفه ی آن بررسی تطابق بین یک String با عبارت باقاعده ی (regular expression) مورد نظر می باشد.
import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; public class RegexMatcher extends TypeSafeMatcher{ private final String regex; public RegexMatcher(final String regex) { this.regex = regex; } @Override public void describeTo(final Description description) { description.appendText("matches regular expression=`" + regex + "`"); } @Override public boolean matchesSafely(final String string) { return string.matches(regex); } // matcher method you can call on this matcher class public static RegexMatcher matchesRegex(final String regex) { return new RegexMatcher(regex); } }
نمونه کد زیر نحوه ی استفاده و پیاده سازی آن را نمایش می دهد.
package com.vogella.android.testing.applicationtest;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
public class TestCustomMatcher {
@Test
public void testRegularExpressionMatcher() throws Exception {
String s ="aaabbbaaaa";
assertThat(s, RegexMatcher.matchesRegex("a*b*a*"));
}
}