JUnit — چارچوبی استاندارد برای آزمونهای واحد در اکوسیستم Java و Kotlin است که در توسعه Android برای بررسی منطق کسبوکار در سطح مؤلفههای جداگانه استفاده میشود. چارچوب مجموعهای از انوتاشها، روشهای assertion و Test Runner را برای کشف و اجرای خودکار آزمونها فراهم میکند. به گزارش JUnit.org، این کتابخانه محبوبترین راهحل برای آزمونهای واحد در اکوسیستم JVM باقی میماند: بیش از 70% پروژههای Java از JUnit در هر نسخهای استفاده میکنند.
نکات کلیدی
JUnit — چارچوبی منبعباز برای نوشتن و اجرای آزمونهای واحد تکرارپذیر به زبان Java و Kotlin است. آن بخشی از اکوسیستم xUnit است — خانواده چارچوبهایی که بر پایه معماری Kent Beck و Erich Gamma ساخته شدهاند و ابزار استاندارد آزمون در Android Studio و IntelliJ IDEA میباشد.
وظیفه اصلی JUnit جداکردن یک بخش کوچک از کد (روش، کلاس) و بررسی رفتار آن در شرایط کنترل شده است. آزمونها به صورت کلاسهای معمولی Java/Kotlin با انوتاشها نوشته میشوند و چارچوب کشف آزمونها، مدیریت چرخه زندگی و جمعآوری آمار اجرای آنها را بر عهده میگیرد.
نسخه اول JUnit در سال 1997 منتشر شد و رویکرد را به طور بنیادین تغییر داد و روشهای Test-Driven Development (TDD) را رایج کرد. امروزه JUnit 5 (Jupiter) نسخه فعلی است که با معماری ماژولایی و پشتیبانی از Java 8+ و افزونهها تماماً بازنویسی شده است.
مکانیزم اجرای JUnit بر پایه الگوی Test Runner استوار دارد که classpath را اسکن میکند، روشهایی را با انوتاشان @Test پیدا میکند، از کلاس آزمون یک نمونه ایجاد میکند و روشها را به ترتیب مشخصی اجرا میکند. Test Runner چرخه زندگی را مدیریت میکند: BeforeAll → BeforeEach → Test → AfterEach → AfterAll.
JUnit هر روش آزمون را در یک نمونه جداگانه از کلاس قرار میدهد که جداگانگی بین آزمونها را تضمین میکند. این به معنای آن است که فیلدهای کلاس وضعیت را بین روشهای @Test مختلف حفظ نمیکنند — هر آزمون با یک شیئٔ پاک آغاز میشود.
سادهترین آزمون در JUnit به صورت یک روش با انوتاشان @Test است که در داخل آن کد مورد آزمون فراخوانی شده و نتیجه از طریق assertion بررسی میشود. اگر assertion موفق نباشد — آزمون شکست خورده دانسته میشود و JUnit خطا را گزارش میدهد.
@Test
void additionShouldReturnCorrectSum() {
var calculator = new Calculator();
var result = calculator.add(2, 3);
assertEquals(5, result);
}
Test Runner به طور خودکار چنین روشی را پیدا میکند، آن را اجرا میکند و نتیجه را گزارش میدهد. اگر روش استثنائی نیندازد — آزمون موفقیت آمیز است (green). اگر assertion کار نکند — آزمون شکست میخورد (red).
انوتاشهای JUnit تعیین میکنند که کد آزمون چه زمانی و چگونه اجرا شود. در JUnit 5 انوتاشها در بسته org.junit.jupiter.api قرار دارند و تمام مراحل را پوشش میدهند: آمادهسازی دادهها، اجرای آزمون، پاکسازی منابع.
| انوتاشان | کاربرد | تعداد اجرا |
|---|---|---|
| @Test | نشانهگذاری روش آزمون | یک بار به ازای هر فراخوانی |
| @BeforeEach | آمادهسازی قبل از هر آزمون | قبل از هر @Test |
| @BeforeAll | مقدمهچینی یکباره کلاس | یک بار قبل از تمامی آزمونها |
| @AfterEach | پاکسازی پس از هر آزمون | پس از هر @Test |
| @AfterAll | پایان یکباره کلاس | یک بار پس از تمامی آزمونها |
| @DisplayName | نام قابل خواندن آزمون | تزئینی |
یک کلاس آزمون کامل با چرخه زندگی مناسب را در نظر بگیرید. روش setUp قبل از هر آزمون یک نمونه تازه از Calculator ایجاد میکند و tearDown منابع را آزاد میکند — به عنوان مثال، بستن دسکریپتورهای فایل یا اتصالات پایگاه داده.
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void subtractionShouldReturnCorrectResult() {
int result = calculator.subtract(10, 4);
assertEquals(6, result);
}
@AfterEach
void tearDown() {
calculator.reset();
}
}
Assertions — روشهایی استاتیک هستند که نتیجه فعلی را با نتیجه مورد انتظار مقایسه میکنند و در صورت ناتجام بودن، استثناء ایجاد میکنند. JUnit 5 کلاس org.junit.jupiter.api.Assertions را با بیش از 25 روش برای سناریوهای مختلف بررسی ارائه میدهد — از مقایسه ساده مقادیر تا بررسی مهلهای زمانی و assertionهای گروهی.
روش assertThrows سزاوار توجه ویژه است که امکان بررسی اینکه کد وضعیتهای خطا را به طور صحیح مدیریت میکند را فراهم میکند — تقسیم بر صفر، ارسال null، تجاوز از حدود.
@Test
void divisionByZeroShouldThrowException() {
Calculator calc = new Calculator();
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> calc.divide(10, 0)
);
assertEquals("Cannot divide by zero", exception.getMessage());
}
آزمونهای پارامتریزه امکان اجرای یک روش آزمون مشابه را با مجموعههای مختلفی از ارگومان فراهم میکنند. در JUnit 5 از انوتاشان @ParameterizedTest در ترکیب با منبع داده — @ValueSource، @CsvSource، @MethodSource یا @EnumSource استفاده میشود.
این رویکرد تکرار کد را به طور چشمگیری کاهش میدهد: به جای ده آزمون یکسان برای مقادیر مختلف، یک روش پارامتریزه نوشته میشود. به گزارش Google Testing Blog، پارامتریزه حجم کد آزمون را 40–60% بدون از دست دادن پوشش کاهش میدهد.
انوتاشان @CsvSource چندین سطر را با جداکننده کاما به آزمون ارسال میکند. هر سطر مربوط به یک اجرای آزمون است. JUnit به طور خودکار مقادیر رشتهای را به انواع مورد نیاز تبدیل میکند: int، long، String و غیره.
@ParameterizedTest
@CsvSource({
"1, 1, 2",
"2, 3, 5",
"10, 20, 30",
"-1, 1, 0"
})
void additionWithMultipleInputs(int a, int b, int expected) {
assertEquals(expected, a + b);
}
زمانی که دادههای ورودی بیش از اعداد یا رشتههای ساده پیچیدهتر هستند، از @MethodSource استفاده میشود. آن به یک روش استاتیک ارجاع میدهد که Streamی از ارگومانها را برمیگرداند — به عنوان مثال، Stream of Arguments یا Stream از شیئهای User برای آزمون لایه DAO.
در توسعه Android، JUnit همراه با AndroidX Test استفاده میشود که افزونههایی برای آزمون Activity، Content Provider و سایر مؤلفههای Android فراهم میکند. JUnit مسئول آزمونهای واحد (unit tests) است که در JVM بدون شبیهساز اجرا میشوند، و AndroidX Test مسئول آزمونهای ابزاری روی دستگاه است.
برای اضافه JUnit 5 به پروژه Android، کافی است وابستگی org.junit.jupiter:junit-jupiter را به build.gradle در سطح ماژول اضافه کنید. افزونه Gradle AGP از اجرای آزمونهای JUnit 5 روی JVM از طریق Test Runner استاندارد پشتیبانی میکند.
// build.gradle.kts
android {
testOptions {
unitTests.isIncludeAndroidResources = true
}
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
testImplementation("androidx.test:core-ktx:1.6.1")
}
در عمل، JUnit بیشتر برای آزمون ViewModel و مخزنها — لایههایی که به زمینه Android یا شبیهساز نیاز ندارند استفاده میشود. چنین آزمونی در چند میلیثانیه اجرا شده و میتواند صدها بار بدون تلف زمان اجرا شود.
JUnit 5 (Jupiter) — فقط یک نسخه جدید نیست، بلکه یک پلتفرم کاملاً بازنویسی شده است که به سه ماژول تقسیم شده: JUnit Platform (اجرای آزمونها روی JVM)، JUnit Jupiter (API برای نوشتن آزمونها) و JUnit Vintage (سازگاری باعکس با JUnit 4). چنین ماژولبندی امکان اتصال مختلف Test Engine را فراهم میکند — به عنوان مثال، Spek برای Kotlin یا TestNG.
| ویژگی | JUnit 4 | JUnit 5 |
|---|---|---|
| بسته | org.junit | org.junit.jupiter |
| انوتاشان پایه | @Test (از junit.framework) | @Test (از org.junit.jupiter.api) |
| Before/After | @Before, @After, @BeforeClass | @BeforeEach, @AfterEach, @BeforeAll |
| Parameterized | @RunWith(Parameterized.class) | @ParameterizedTest + @ValueSource |
| Extension | @Rule, @ClassRule | @ExtendWith, API انعطافپذیرتر |
| Java min | Java 5 | Java 8+ |
مهاجرت از JUnit 4 به JUnit 5 نیازی به تمامی آزمونها ندارد — کافی است JUnit Vintage Engine را متصل کنید و آزمونهای قدیمی به کار خود ادامه خواهند داد. توصیه میشود آزمونهای جدید را در JUnit 5 بنویسید تا از افزونهها، لامبدا در assertionها و پشتیبانی داخلی از پارامتریزه استفاده کنید.
سؤالات متداول
JUnit — چارچوبی برای نوشتن و اجرای آزمونهاست و Mockito کتابخانهای برای ایجاد شیئهای mock است. آنها با هم استفاده میشوند: JUnit اجرای آزمون را مدیریت میکند و Mockito وابستگیهای کلاس مورد آزمون را جایگزین میکند.
بله، JUnit 5 کاملاً با پروژههای Android سازگار است. برای آزمونهای واحد کافی است وابستگی junit-jupiter را به build.gradle اضافه کنید. آزمونهای ابزاری همچنان از طریق AndroidX Test Runner کار میکنند.
حداقل یک انوتاشان @Test قبل از روش کافی است. برای مقدمهچینی و پاکسازی @BeforeEach و @AfterEach توصیه میشوند، اما اجباری نیستند.
Test Runner — مؤلفهای از JUnit است که classpath را اسکن میکند، روشهایی را با انوتاشان @Test پیدا میکند، از کلاسهای آزمون نمونه ایجاد میکند و آزمونها را اجرا میکند. در JUnit 5 این نقش را JUnit Platform با Test Engineهای متصل ایفا میکند.
از assertThrows(Class, Executable) استفاده کنید — آن نوع استثناء مورد انتظار و لامبدایی با فراخوانی روش را میپذیرد. JUnit بررسی میکند که استثناء واقعاً تولید شده است و آن را برای بررسی بیشتر بازمیگرداند.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید