ЛЕКЦ 03: ПРОГРАМ ХАНГАМЖИЙН ТЕСТЧИЛЭЛ (Software Testing)
Хичээлийн зорилго: Програм хангамжийн тестчилэлийн суурь ойлголт, аргачлалууд, түвшнүүд, JUnit фреймворк ашиглан тест бичих чадвар эзэмшүүлэх.
Хамрах хүрээ: Тестчилэлийн түвшнүүд, Unit Testing, Integration Testing, TDD, JUnit 5, Code Coverage, тест стратегиуд.
ХЭСЭГ 1: ОНОЛЫН СУУРЬ (Theory & Foundations)
1.1 Тестчилэл гэж юу вэ?
Програм хангамжийн тестчилэл (Software Testing) гэдэг нь програм зөв ажиллаж байгаа эсэхийг шалгах, алдааг (bug) олох, чанарыг баталгаажуулах процесс юм.
🔑 IEEE тодорхойлолт: "Тестчилэл нь програмыг хүлээгдэж буй үр дүнтэй нь харьцуулж, зөрүүг олох процесс."
Тестчилэл яагаад чухал вэ?
Барилга барьж дууссаны дараа газар хөдлөлтийн шалгалт хийдэг шиг, програм хангамж мөн хэрэглэгчид хүрэхээс өмнө сайтар шалгагдах ёстой.
Бодит жишээ — Алдааны үнэ:
| Алдааг олсон үе шат | Засах зардал (харьцангуй) |
|---|---|
| Шаардлага тодорхойлолт | 1× |
| Дизайн | 5× |
| Кодчилол | 10× |
| Тестчилэл | 20× |
| Хэрэглэгчид хүрсний дараа | 100× |
💡 Зүйрлэл: Хувцас оёхдоо хэмжилт алдвал эхэндээ засахад хялбар. Бэлэн хувцас болсны дараа засвар хийхэд их цаг, мөнгө шаардагдана. Код мөн адил.
Тестчилэлийн гол зорилгууд:
- Алдаа олох — Код дахь буруу логик, бичлэгийн алдааг олж засах
- Чанар баталгаажуулах — Шаардлагын дагуу зөв ажиллаж байгааг батлах
- Итгэлцэл бий болгох — Програмд итгэж болно гэсэн баталгаа
- Регрессийн хамгаалалт — Шинэ код нэмэхэд хуучин функц эвдрэхгүй байх
- Баримтжуулалт — Тест нь кодын зан төлөвийн "амьд" баримт бичиг
1.2 Тестчилэлийн суурь зарчмууд (7 зарчим — ISTQB)
ISTQB (International Software Testing Qualifications Board) нь 7 суурь зарчмыг тодорхойлсон:
Зарчим 1: Тестчилэл нь алдаа байгааг харуулдаг, алдаагүйг биш
Зүйрлэл: Шөнийн харанхуйд гэрлээр гэрийг шалгахад бөөс олдсон бол — бөөс БАЙНА гэсэн үг. Олдоогүй бол — БАЙХГҮЙ гэсэн үг БИШ, зүгээр олдоогүй гэсэн үг.
Тестчилэл нь алдааг олж чадна, гэхдээ алдаа огт байхгүй гэдгийг батлах чадваргүй. 100 тест дамжсан ч 101 дэх тохиолдолд алдаа гарч болно.
Зарчим 2: Бүрэн тестчилэл боломжгүй (Exhaustive testing is impossible)
Зүйрлэл: Хэрэв нэг функц 3 параметр авдаг, параметр бүр 100 утга авч болдог бол: 100 × 100 × 100 = 1,000,000 тохиолдол. Бүгдийг тестлэх боломжгүй!
Бүх оролт, бүх нөхцөлийг тестлэх нь бараг боломжгүй. Тиймээс эрсдэлд суурилсан тест стратеги ашиглана.
Зарчим 3: Эрт тестлэх (Early testing)
Зүйрлэл: Хорт хавдрыг эрт оношлох тусмаа эдгэрэх магадлал өндөр. Алдааг эрт олох тусмаа засах зардал бага.
Тестчилэлийг зөвхөн кодчилол дууссаны дараа биш, шаардлага, дизайны шатнаас эхлэх ёстой.
Зарчим 4: Алдааны бөөгнөрөл (Defect clustering)
Зүйрлэл: "Парето зарчим" — Алдааны 80% нь кодын 20%-д байдаг.
Програмын нарийн төвөгтэй, олон удаа өөрчлөгдсөн хэсгүүдэд алдаа бөөгнөрдөг. Тэр хэсгүүдэд анхаарал төвлөрүүлэх ёстой.
Зарчим 5: Хортон шавжны эм (Pesticide paradox)
Зүйрлэл: Нэг л хортон шавжны эмийг давтан хэрэглэвэл шавж дасдаг. Ижил тестийг давтвал шинэ алдаа олдохгүй.
Тестийг байнга шинэчлэх, шинэ тохиолдлууд нэмэх шаардлагатай. Хуучин тестээр шинэ алдаа олдохгүй.
Зарчим 6: Тестчилэл нь контекстаас хамаарна
Зүйрлэл: Нисэх онгоцны програм ба мобайл тоглоомын тест адилхан биш. Нисэх онгоцны программ алдаа гаргавал хүмүүсийн амь насанд аюултай, тоглоом алдаа гаргавал зүгээр дахин эхэлнэ.
Тестийн стратеги нь програмын төрөл, эрсдэл, зорилго-оос хамаарна.
Зарчим 7: Алдаагүй гэсэн төөрөгдөл (Absence-of-errors fallacy)
Зүйрлэл: 0 алдаатай програм ч хэрэглэгчийн шаардлагад нийцэхгүй байж болно.
Алдаагүй програм ≠ Зөв програм. Програм хэрэглэгчийн хэрэгцээг хангаж чадаж байгаа эсэх нь чухал.
1.3 Тестчилэлийн түвшнүүд (Testing Levels)
Тестчилэл нь пирамид бүтэцтэй — доороос дээш:
▲
/ \ ← E2E Testing (Системийн бүрэн тест)
/ \ Удаан, цөөн
/ \
/ Integra-\ ← Integration Testing (Нэгтгэлийн тест)
/ tion \ Дунд зэрэг
/ \
/ Unit Testing \ ← Unit Testing (Нэгж тест)
/ \ Хурдан, маш олон
/___________________\
1.3.1 Unit Testing (Нэгж тест)
Тодорхойлолт: Кодын хамгийн ЖИЖИГ нэгжийг (метод, функц) тусад нь шалгах.
Зүйрлэл: Машинд суурилуулахаас өмнө мотор, тоормос, гэрэл тус бүрийг ТУСАД НЬ шалгах. Мотор зөв ажиллаж байна уу? Тоормос зөв зогсоож байна уу?
Онцлог:
- Хамгийн хурдан — миллисекунд хугацаанд ажиллана
- Хамгийн олон — тестийн 70-80% нь unit тест
- Хамгийн хямд — олж засахад хялбар
- Хөгжүүлэгч бичдэг — код бичсэн хүн бичнэ
// Unit тестийн жишээ — Calculator классын нэмэх методыг тестлэх
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3)); // 2 + 3 = 5 байх ёстой
}
@Test
void testAddNegative() {
Calculator calc = new Calculator();
assertEquals(-1, calc.add(2, -3)); // 2 + (-3) = -1 байх ёстой
}
@Test
void testAddZero() {
Calculator calc = new Calculator();
assertEquals(0, calc.add(0, 0)); // 0 + 0 = 0 байх ёстой
}
}
1.3.2 Integration Testing (Нэгтгэлийн тест)
Тодорхойлолт: Олон модуль, компонентыг НЭГТГЭЖ шалгах. Модулиуд хоорондоо зөв харилцаж байгаа эсэхийг баталгаажуулах.
Зүйрлэл: Мотор, тоормос, хурдны хайрцаг тус бүрдээ зөв ажилладаг ч хамтдаа зөв ажиллаж байгаа эсэхийг шалгах. Мотор хурдны хайрцагтай зөв холбогдож байна уу?
Нэгтгэлийн тестийн аргууд:
| Арга | Тайлбар | Зүйрлэл |
|---|---|---|
| Big Bang | Бүх модулийг нэг дор нэгтгэж тестлэх | Бүх эд ангийг нэг дор угсарч шалгах |
| Top-Down | Дээрээс доош нэгтгэж тестлэх | Дээврээс эхэлж барилга барих |
| Bottom-Up | Доороос дээш нэгтгэж тестлэх | Суурьнаас эхэлж барилга барих |
| Sandwich | Top-Down + Bottom-Up хослуулах | Дундаас хоёр зүгт зэрэг барих |
// Integration тестийн жишээ — UserService ба Database хамтран ажиллаж байгааг шалгах
class UserServiceIntegrationTest {
@Test
void testRegisterAndFindUser() {
Database db = new Database("test.db");
UserService service = new UserService(db);
// Хэрэглэгч бүртгэх
service.register("Бат", "bat@email.com");
// Бүртгэсэн хэрэглэгчийг олох
User found = service.findByEmail("bat@email.com");
assertNotNull(found); // Олдсон байх ёстой
assertEquals("Бат", found.getName()); // Нэр тохирч байх ёстой
}
}
1.3.3 System Testing (Системийн тест)
Тодорхойлолт: Бүхэл системийг шаардлагын дагуу ажиллаж байгаа эсэхийг шалгах.
Зүйрлэл: Бүрэн угсарсан машиныг замд гаргаж жолоодож шалгах — бүх зүйл хамтдаа зөв ажиллаж байна уу?
1.3.4 Acceptance Testing (Хүлээн авах тест)
Тодорхойлолт: Хэрэглэгч / захиалагч системийг хүлээн авахын өмнө хийх тест.
Зүйрлэл: Машин худалдан авагч жолоодож туршаад "тийм, энэ машин надад тохирч байна" гэж хэлэх.
Төрлүүд:
- Alpha тест — Хөгжүүлэгч байгууллагын дотор
- Beta тест — Бодит хэрэглэгчдэд тарааж шалгуулах
- UAT (User Acceptance Testing) — Захиалагч шалгах
1.4 Тестийн аргачлалууд (Testing Techniques)
1.4.1 Хар хайрцагны тест (Black-Box Testing)
Тодорхойлолт: Кодын дотоод бүтцийг МЭДЭХГҮЙГЭЭР, зөвхөн оролт → гаралтыг шалгах.
Зүйрлэл: Вендинг машин. Мөнгө хийж, товч дарна → Бүтээгдэхүүн гарна. Дотор нь яаж ажиллаж байгааг мэдэх шаардлагагүй.
Техникүүд:
а) Эквивалент ангилал (Equivalence Partitioning)
Оролтыг "ижил зан төлөвтэй" бүлгүүдэд хуваана. Бүлэг бүрээс нэг утга тестлэхэд хангалттай.
Жишээ: Насны баталгаажуулалт (18-65 зөвшөөрөгддөг)
├── Бүлэг 1: < 18 (буруу) → Тест: 10
├── Бүлэг 2: 18-65 (зөв) → Тест: 30
└── Бүлэг 3: > 65 (буруу) → Тест: 70
б) Хил заагийн шинжилгээ (Boundary Value Analysis)
Хилийн утгууд дээр алдаа хамгийн их гардаг → Хилийн утгуудыг онцгойлон тестлэх.
Жишээ: Насны баталгаажуулалт (18-65)
Тестлэх утгууд: 17, 18, 19, 64, 65, 66
↑ ↑ ↑ ↑
Хилийн утгууд дээр алдаа их гардаг!
в) Шийдвэрийн хүснэгт (Decision Table)
Олон нөхцөлийн хослолуудыг хүснэгтээр тестлэх:
| Нөхцөл | Тест 1 | Тест 2 | Тест 3 | Тест 4 |
|-----------------|--------|--------|--------|--------|
| Нас >= 18 | Тийм | Тийм | Үгүй | Үгүй |
| Жолооны үнэмлэх | Тийм | Үгүй | Тийм | Үгүй |
| Машин жолоодох | ✅ Зөв | ❌ Буруу | ❌ Буруу | ❌ Буруу |
1.4.2 Цагаан хайрцагны тест (White-Box Testing)
Тодорхойлолт: Кодын дотоод бүтцийг МЭДЭЖ, бүх замналуудыг шалгах.
Зүйрлэл: Машины механик моторыг задалж, дотоод эд анги бүрийг шалгах.
Техникүүд:
а) Мэдэгдлийн хамралт (Statement Coverage)
Кодын бүх мэдэгдэл (statement) дор хаяж 1 удаа ажиллаж байгааг шалгах.
// Шалгах код
public String getGrade(int score) {
if (score >= 90) { // Мэдэгдэл 1
return "A"; // Мэдэгдэл 2
} else if (score >= 80) { // Мэдэгдэл 3
return "B"; // Мэдэгдэл 4
} else {
return "F"; // Мэдэгдэл 5
}
}
// 100% statement coverage-д:
// Тест 1: score = 95 → "A" (Мэдэгдэл 1, 2)
// Тест 2: score = 85 → "B" (Мэдэгдэл 3, 4)
// Тест 3: score = 50 → "F" (Мэдэгдэл 5)
б) Салаалтын хамралт (Branch Coverage)
Бүх if/else салаалтын TRUE ба FALSE замыг тестлэх.
в) Замналын хамралт (Path Coverage)
Кодын бүх боломжит замналуудыг тестлэх — хамгийн иж бүрэн гэхдээ хамгийн их хүчин чармайлт шаарддаг.
1.4.3 Саарал хайрцагны тест (Grey-Box Testing)
Хар + Цагаан хайрцагны хослол. Дотоод бүтцийн ЗАРИМ мэдлэгтэй байж тестлэх.
Зүйрлэл: Машины механик мотороо мэддэг (цагаан) гэхдээ дотор бүрэн задлахгүйгээр, гаднаас оношлох (хар). Хоёрыг хослуулах.
1.5 Test-Driven Development (TDD)
TDD нь "Тестээ ЭХЛЭЭД бич, дараа нь кодоо бич" гэсэн хөгжүүлэлтийн арга.
TDD-ийн 3 алхам (Red-Green-Refactor):
┌─────────┐
│ 🔴 RED │ ← 1. Шинэ тест бич (тест FAIL болно)
└────┬────┘
│
┌────▼────┐
│ 🟢 GREEN│ ← 2. Тестийг дамжуулах ХАМГИЙН БАГА кодыг бич
└────┬────┘
│
┌────▼─────┐
│🔵REFACTOR│ ← 3. Кодыг цэвэрлэ, сайжруул (тест дахин дамждаг)
└────┬─────┘
│
└─────── 🔄 Давтана
TDD-ийн бодит жишээ: FizzBuzz
Даалгавар: 1-100 хүртэлх тоонуудыг хэвлэх. 3-д хуваагддаг бол "Fizz", 5-д хуваагддаг бол "Buzz", хоёуланд нь хуваагддаг бол "FizzBuzz".
Алхам 1 — 🔴 RED: Тест бичих
@Test
void testFizzBuzzOf1() {
assertEquals("1", FizzBuzz.convert(1)); // 1 → "1"
}
Алхам 2 — 🟢 GREEN: Хамгийн бага кодыг бичих
class FizzBuzz {
public static String convert(int number) {
return String.valueOf(number); // Зүгээр тоог String болгох
}
}
Алхам 3 — 🔴 RED: Шинэ тест нэмэх
@Test
void testFizzBuzzOf3() {
assertEquals("Fizz", FizzBuzz.convert(3)); // 3 → "Fizz"
}
Алхам 4 — 🟢 GREEN: Кодыг өргөтгөх
class FizzBuzz {
public static String convert(int number) {
if (number % 3 == 0) return "Fizz";
return String.valueOf(number);
}
}
Алхам 5 — 🔴 RED → 🟢 GREEN: 5-д хуваагддаг
@Test
void testFizzBuzzOf5() {
assertEquals("Buzz", FizzBuzz.convert(5)); // 5 → "Buzz"
}
// Код:
class FizzBuzz {
public static String convert(int number) {
if (number % 3 == 0 && number % 5 == 0) return "FizzBuzz";
if (number % 3 == 0) return "Fizz";
if (number % 5 == 0) return "Buzz";
return String.valueOf(number);
}
}
TDD-ийн давуу ба сул талууд:
| Давуу тал | Сул тал |
|---|---|
| Алдааг эрт олдог | Эхэндээ удаан |
| Кодын чанар сайжирдаг | Сурах муруй өндөр |
| Дахин засварлахад (refactor) итгэлтэй | Бүх нөхцөлд тохирохгүй (UI тест) |
| Баримтжуулалт болдог | Тест maintenance шаардагддаг |
| Дизайныг сайжруулдаг | Хэт нарийн тестчилэлд хүргэж болно |
1.6 JUnit 5 фреймворк
JUnit нь Java-ийн хамгийн алдартай unit тестийн фреймворк. JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage.
JUnit 5-ийн гол аннотациуд:
| Аннотаци | Зорилго | Зүйрлэл |
|---|---|---|
@Test | Метод нь тест гэдгийг заах | "Энэ бол шалгалт" гэсэн шошго |
@BeforeEach | Тест бүрийн өмнө ажиллах | Шалгалтын өмнө ширээ цэвэрлэх |
@AfterEach | Тест бүрийн дараа ажиллах | Шалгалтын дараа ширээ цэвэрлэх |
@BeforeAll | Бүх тестийн өмнө 1 удаа ажиллах | Шалгалтын өрөө бэлтгэх |
@AfterAll | Бүх тестийн дараа 1 удаа ажиллах | Шалгалтын өрөө хаах |
@DisplayName | Тестийн нэрийг тодорхойлох | Шалгалтын асуултын гарчиг |
@Disabled | Тестийг түр хаах | "Энэ асуултыг алгас" |
@ParameterizedTest | Олон утгаар тестлэх | Олон оюутнаар ижил шалгалт авах |
@RepeatedTest | Тестийг олон удаа давтах | Шалгалтыг давтан авах |
JUnit 5-ийн гол assert методууд:
// Тэнцүү эсэх
assertEquals(expected, actual); // expected == actual
assertNotEquals(unexpected, actual); // unexpected != actual
// Null эсэх
assertNull(object); // object == null
assertNotNull(object); // object != null
// Boolean
assertTrue(condition); // condition == true
assertFalse(condition); // condition == false
// Exception шалгах
assertThrows(Exception.class, () -> {
// Exception үүсгэх код
});
// Хугацааны хязгаар
assertTimeout(Duration.ofSeconds(2), () -> {
// 2 секундэд дуусах ёстой код
});
// Массив тэнцүү эсэх
assertArrayEquals(expectedArray, actualArray);
JUnit 5 бүрэн жишээ: BankAccount тест
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
// ===== Тестлэх класс =====
class BankAccount {
private String owner;
private double balance;
public BankAccount(String owner, double initialBalance) {
if (initialBalance < 0) {
throw new IllegalArgumentException("Анхны үлдэгдэл сөрөг байж болохгүй");
}
this.owner = owner;
this.balance = initialBalance;
}
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Нэмэх дүн 0-ээс их байх ёстой");
}
balance += amount;
}
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Авах дүн 0-ээс их байх ёстой");
}
if (amount > balance) {
throw new IllegalStateException("Үлдэгдэл хүрэлцэхгүй байна");
}
balance -= amount;
}
public double getBalance() { return balance; }
public String getOwner() { return owner; }
}
// ===== Тест класс =====
class BankAccountTest {
private BankAccount account;
@BeforeEach
void setUp() {
// Тест бүрийн өмнө шинэ данс үүсгэнэ
account = new BankAccount("Бат", 10000);
}
@Test
@DisplayName("Данс үүсгэхэд үлдэгдэл зөв байх")
void testInitialBalance() {
assertEquals(10000, account.getBalance());
assertEquals("Бат", account.getOwner());
}
@Test
@DisplayName("Мөнгө нэмэхэд үлдэгдэл нэмэгдэх")
void testDeposit() {
account.deposit(5000);
assertEquals(15000, account.getBalance()); // 10000 + 5000
}
@Test
@DisplayName("Мөнгө авахад үлдэгдэл хасагдах")
void testWithdraw() {
account.withdraw(3000);
assertEquals(7000, account.getBalance()); // 10000 - 3000
}
@Test
@DisplayName("Үлдэгдэлээс их мөнгө авахад алдаа гарах")
void testWithdrawInsufficientFunds() {
assertThrows(IllegalStateException.class, () -> {
account.withdraw(50000); // 10000-аас их → Алдаа!
});
}
@Test
@DisplayName("Сөрөг дүн нэмэхэд алдаа гарах")
void testDepositNegativeAmount() {
assertThrows(IllegalArgumentException.class, () -> {
account.deposit(-1000); // Сөрөг дүн → Алдаа!
});
}
@Test
@DisplayName("Сөрөг анхны үлдэгдлээр данс үүсгэхэд алдаа гарах")
void testNegativeInitialBalance() {
assertThrows(IllegalArgumentException.class, () -> {
new BankAccount("Болд", -5000); // Сөрөг → Алдаа!
});
}
@Test
@DisplayName("Олон удаа мөнгө нэмж авахад зөв тооцоолох")
void testMultipleTransactions() {
account.deposit(5000); // 10000 + 5000 = 15000
account.withdraw(3000); // 15000 - 3000 = 12000
account.deposit(1000); // 12000 + 1000 = 13000
assertEquals(13000, account.getBalance());
}
}
1.7 Code Coverage (Кодын хамралт)
Code Coverage гэдэг нь тестээр кодын хэдэн хувь хамрагдсан бэ гэдгийг хэмждэг.
Зүйрлэл: Гэрийн шалгалтаар бүх өрөө шалгагдсан уу? 10 өрөөнөөс 8-ыг шалгасан бол 80% хамралт.
Хамралтын төрлүүд:
| Төрөл | Тайлбар | Жишээ |
|---|---|---|
| Statement Coverage | Кодын мөр бүр ажиллаж байна уу | 20 мөрнөөс 18 ажилласан → 90% |
| Branch Coverage | if/else бүр хоёр чиглэлд тестлэгдсэн үү | 10 салаанаас 8 тестлэгдсэн → 80% |
| Method Coverage | Метод бүр дуудагдсан уу | 5 методоос 5 дуудагдсан → 100% |
| Line Coverage | Мөр бүр ажиллаж байна уу | Statement Coverage-тэй төстэй |
Хамралтын зөвлөмж:
| Хамралтын түвшин | Үнэлгээ |
|---|---|
| < 50% | ❌ Маш муу — олон алдаа нуугдаж байна |
| 50-70% | ⚠️ Дунд зэрэг — сайжруулах хэрэгтэй |
| 70-85% | ✅ Сайн — ихэнх төслийн стандарт |
| 85-95% | ✅ Маш сайн — чухал системүүдэд зөвлөгддөг |
| 100% | ⚠️ Хэтэрхий — 100% хамралт ≠ 100% алдаагүй |
⚠️ Анхааруулга: 100% coverage нь алдаагүй гэсэн үг биш! Тест нь зөв зүйлийг шалгаж байгаа эсэх (test quality) нь coverage-ээс чухал.
1.8 Тестийн сайн практикууд (Best Practices)
AAA загвар (Arrange-Act-Assert):
@Test
void testDiscount() {
// ARRANGE — Бэлтгэх
Product product = new Product("Ном", 20000);
DiscountService service = new DiscountService();
// ACT — Үйлдэл хийх
double discountedPrice = service.applyDiscount(product, 10);
// ASSERT — Шалгах
assertEquals(18000, discountedPrice); // 20000 - 10% = 18000
}
FIRST зарчмууд:
| Зарчим | Англи | Монгол тайлбар |
|---|---|---|
| F | Fast | Тест ХУРДАН ажиллах ёстой |
| I | Independent | Тестүүд бие биенээсээ ХАМААРАЛГҮЙ |
| R | Repeatable | Хэзээ ч ажиллуулсан ИЖИЛ үр дүн |
| S | Self-validating | Тест ӨӨрӨӨ ЗӨРҮҮ/ДАМЖСАН гэж хариулах |
| T | Timely | Тестийг ЦАГТ НЬ бичих (кодтой зэрэг) |
Нэг тест — нэг зүйл шалгах:
// ❌ БУРУУ — олон зүйл нэг тестэд
@Test
void testEverything() {
assertEquals(5, calc.add(2, 3));
assertEquals(6, calc.multiply(2, 3)); // Хоёр өөр функц нэг тестэд
assertNotNull(calc.toString());
}
// ✅ ЗӨӨВ — тус тусдаа
@Test
void testAdd() {
assertEquals(5, calc.add(2, 3));
}
@Test
void testMultiply() {
assertEquals(6, calc.multiply(2, 3));
}
Тестийн нэрлэх дүрэм:
// Загвар: methodName_condition_expectedResult
@Test void add_twoPositiveNumbers_returnsSum() { ... }
@Test void withdraw_insufficientBalance_throwsException() { ... }
@Test void login_invalidPassword_returnsFalse() { ... }
1.9 Mock ба Stub
Тестлэх объект бусад объектоос хамааралтай бол Mock ба Stub ашиглана.
Зүйрлэл: Жүжигчин бодит дайсантай биш, хиймэл манекентай дасгал хийдэг шиг — тест бодит мэдээллийн сантай биш, хиймэл объекттой ажиллана.
Stub vs Mock:
| Stub | Mock | |
|---|---|---|
| Зорилго | Бэлэн хариу буцаах | Зан төлөвийг шалгах |
| Зүйрлэл | Автомат хариулагч машин | Хэн юу хэлснийг бичиж авдаг нарийн бичгийн дарга |
| Шалгах зүйл | Гаралтын утга | Метод дуудагдсан эсэх, хэдэн удаа дуудагдсан |
// Stub жишээ — Тогтмол хариу буцаадаг
class StubEmailService implements EmailService {
@Override
public boolean send(String to, String message) {
return true; // Үргэлж амжилттай гэж буцаана
}
}
// Mock жишээ (Mockito ашиглан)
@Test
void testUserRegistration() {
EmailService mockEmail = mock(EmailService.class); // Mock үүсгэх
UserService service = new UserService(mockEmail);
service.register("Бат", "bat@email.com");
// Баталгаажуулах: send метод 1 удаа дуудагдсан уу?
verify(mockEmail, times(1)).send(eq("bat@email.com"), anyString());
}
1.10 Тестийн төрлүүд (Functional vs Non-Functional)
Функциональ тест (Functional Testing):
Систем юу хийдэг-ийг шалгана.
| Төрөл | Тайлбар |
|---|---|
| Unit Test | Нэгж функцийн шалгалт |
| Integration Test | Модулиудын хамтын ажиллагаа |
| System Test | Бүхэл системийн шалгалт |
| Acceptance Test | Хэрэглэгчийн шаардлага хангаж буй эсэх |
| Regression Test | Шинэ код хуучин функцийг эвдсэн эсэх |
| Smoke Test | Системийн суурь функцүүд ажиллаж байна уу (хурдан шалгалт) |
Функциональ бус тест (Non-Functional Testing):
Систем яаж хийдэг-ийг шалгана.
| Төрөл | Тайлбар | Зүйрлэл |
|---|---|---|
| Performance Test | Хурд, хариу өгөх хугацаа | Машин хэр хурдан вэ? |
| Load Test | Ачаалал дор ажиллагаа | 1000 хүн нэг зэрэг нэвтэрвэл? |
| Stress Test | Хязгаарын ачаалал | Машин хамгийн ихдээ хэр хурдалж чадах вэ? |
| Security Test | Аюулгүй байдал | Хаалга, цонх түгжигдсэн үү? |
| Usability Test | Хэрэглэхэд хялбар эсэх | Машин жолоодоход хялбар уу? |
| Compatibility Test | Өөр орчинд ажиллах эсэх | Машин шороон замд ч зүгээр юу? |
ХЭСЭГ 2: ТҮЛХҮҮР ҮГ БА МЭРГЭЖЛИЙН НЭР ТОМЬЁО (Keywords & Glossary)
| # | Англи нэр томьёо | Монгол утга | Дэлгэрэнгүй тайлбар |
|---|---|---|---|
| 1 | Software Testing | Програм хангамжийн тестчилэл | Програм зөв ажиллаж байгаа эсэхийг шалгах, алдааг олох, чанарыг баталгаажуулах процесс. |
| 2 | Unit Testing | Нэгж тест | Кодын хамгийн жижиг нэгжийг (метод, функц) тусад нь шалгах. Хамгийн хурдан, хамгийн олон тест. |
| 3 | Integration Testing | Нэгтгэлийн тест | Олон модуль нэгдэж зөв ажиллаж байгаа эсэхийг шалгах. |
| 4 | System Testing | Системийн тест | Бүхэл системийг шаардлагын дагуу шалгах. |
| 5 | Acceptance Testing | Хүлээн авах тест | Хэрэглэгч / захиалагч системийг хүлээн авахын өмнө хийх тест. |
| 6 | Regression Testing | Регрессийн тест | Шинэ код хуучин функцийг эвдсэн эсэхийг шалгах. |
| 7 | Smoke Testing | Утааны тест | Системийн суурь функцүүд ажиллаж байна уу гэдгийг хурдан шалгах. |
| 8 | Black-Box Testing | Хар хайрцагны тест | Кодын дотоод бүтцийг мэдэхгүйгээр оролт → гаралтыг шалгах. |
| 9 | White-Box Testing | Цагаан хайрцагны тест | Кодын дотоод бүтцийг мэдэж бүх замналуудыг шалгах. |
| 10 | Grey-Box Testing | Саарал хайрцагны тест | Хар + Цагаан хайрцагны хослол. Дотоод бүтцийн зарим мэдлэгтэй. |
| 11 | TDD (Test-Driven Development) | Тестэнд суурилсан хөгжүүлэлт | Тестээ эхлээд бичиж, дараа нь кодоо бичих арга. Red-Green-Refactor цикл. |
| 12 | BDD (Behavior-Driven Development) | Зан төлөвд суурилсан хөгжүүлэлт | Хэрэглэгчийн зан төлөвөөс эхлэн тест, код бичих. Given-When-Then загвар. |
| 13 | JUnit | Жи-Юнит | Java-ийн хамгийн алдартай unit тестийн фреймворк. |
| 14 | Test Case | Тестийн тохиолдол | Нэг тодорхой нөхцөлд системийн зан төлөвийг шалгах тест. |
| 15 | Test Suite | Тестийн багц | Хэд хэдэн test case-ийг бүлэглэсэн цуглуулга. |
| 16 | Assertion | Баталгаа / Нотолгоо | Тестийн хүлээгдэж буй үр дүнг бодит үр дүнтэй харьцуулах. assertEquals, assertTrue гэх мэт. |
| 17 | Code Coverage | Кодын хамралт | Тестээр кодын хэдэн хувь хамрагдсан бэ гэдгийг хэмждэг. |
| 18 | Statement Coverage | Мэдэгдлийн хамралт | Кодын мөр бүр дор хаяж 1 удаа ажиллаж байгааг шалгах. |
| 19 | Branch Coverage | Салаалтын хамралт | if/else бүр хоёр чиглэлд тестлэгдсэн эсэхийг шалгах. |
| 20 | Mock | Хиймэл объект (Мок) | Бодит объектын оронд ашигладаг хиймэл объект. Зан төлөвийг шалгахад ашигладаг. |
| 21 | Stub | Орлуулагч (Стаб) | Тогтмол хариу буцаадаг хялбар хиймэл объект. |
| 22 | Bug / Defect | Алдаа / Согог | Кодын буруу ажиллагаа. Хүлээгдэж буй үр дүнгээс зөрүү. |
| 23 | Equivalence Partitioning | Эквивалент ангилал | Оролтыг ижил зан төлөвтэй бүлгүүдэд хуваах. Бүлэг бүрээс нэг утга тестлэх. |
| 24 | Boundary Value Analysis | Хил заагийн шинжилгээ | Хилийн утгууд дээр алдаа их гардаг → Хилийн утгуудыг онцгойлон тестлэх. |
| 25 | Decision Table | Шийдвэрийн хүснэгт | Олон нөхцөлийн хослолуудыг хүснэгтээр тестлэх арга. |
| 26 | AAA Pattern | AAA загвар | Arrange (бэлтгэх) → Act (үйлдэл хийх) → Assert (шалгах). Тестийн бүтцийн загвар. |
| 27 | FIRST Principles | FIRST зарчим | Fast, Independent, Repeatable, Self-validating, Timely — Сайн тестийн 5 чанар. |
| 28 | Red-Green-Refactor | Улаан-Ногоон-Дахин засвар | TDD-ийн 3 алхам: Тест fail → Тест pass → Код цэвэрлэх. |
| 29 | Test Fixture | Тестийн тохиргоо | Тест ажиллуулахад шаардлагатай бэлтгэлийн өгөгдөл, объектууд. |
| 30 | @Test | Тест аннотаци | JUnit-д метод нь тест гэдгийг заах аннотаци. |
| 31 | @BeforeEach | Тест бүрийн өмнө | Тест бүрийн өмнө ажиллах setup метод. |
| 32 | @AfterEach | Тест бүрийн дараа | Тест бүрийн дараа ажиллах teardown метод. |
| 33 | @ParameterizedTest | Параметрчилсэн тест | Олон утгаар нэг тестийг давтах. |
| 34 | assertThrows | Exception шалгах | Тодорхой exception үүсгэж байгаа эсэхийг шалгах assert метод. |
| 35 | Performance Testing | Гүйцэтгэлийн тест | Системийн хурд, хариу өгөх хугацааг шалгах. |
| 36 | Load Testing | Ачааллын тест | Олон хэрэглэгчийн ачаалал дор системийн ажиллагааг шалгах. |
| 37 | Stress Testing | Хүчний тест | Системийн хязгаарын ачааллыг шалгах. |
| 38 | Security Testing | Аюулгүй байдлын тест | Системийн аюулгүй байдлыг шалгах. |
| 39 | Test Pyramid | Тестийн пирамид | Unit тест олон, Integration дунд, E2E цөөн байх бүтэц. |
| 40 | Continuous Testing | Тасралтгүй тестчилэл | CI/CD дамжуулгад тест автоматаар ажиллуулах. Код push хийх бүрт тест ажиллана. |
ХЭСЭГ 3: ЛАБОРАТОРИ БА ПРАКТИК ЗААВАР (Labs & Step-by-Step Guide)
3.1 Лабораторийн зорилго
Энэ лабораторид та JUnit 5 ашиглан unit тест бичих чадвар эзэмшинэ:
- JUnit 5 суулгах ба анхны тест бичих
- Хил заагийн шинжилгээ (Boundary Value) ашиглан тестлэх
- Exception тестлэх
- TDD аргаар шинэ функц хөгжүүлэх
Шаардлагатай зүйлс: Java JDK 17+, Eclipse IDE, Maven
3.2 Лаб 1: JUnit 5 суулгах ба анхны тест
Алхам 1: Eclipse-д шинэ Maven төсөл үүсгэнэ (File → New → Maven Project): TestingLab
Алхам 2: pom.xml файлд JUnit 5 хамаарлыг нэмнэ:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Алхам 3: src/main/java дотор StringUtils.java үүсгэнэ:
public class StringUtils {
// Тэмдэгт мөрийг урвуулах
public static String reverse(String str) {
if (str == null) {
throw new IllegalArgumentException("null утга оруулж болохгүй");
}
return new StringBuilder(str).reverse().toString();
}
// Palindrome мөн эсэхийг шалгах (урд хойноосоо адилхан)
public static boolean isPalindrome(String str) {
if (str == null) {
throw new IllegalArgumentException("null утга оруулж болохгүй");
}
String cleaned = str.toLowerCase().replaceAll("\\s+", "");
return cleaned.equals(new StringBuilder(cleaned).reverse().toString());
}
// Үгийн тоог тоолох
public static int countWords(String str) {
if (str == null || str.trim().isEmpty()) {
return 0;
}
return str.trim().split("\\s+").length;
}
// Эхний үсгийг том болгох
public static String capitalize(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
Алхам 4: src/test/java дотор StringUtilsTest.java үүсгэнэ:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;
class StringUtilsTest {
// === reverse() тестүүд ===
@Test
@DisplayName("Энгийн мөр урвуулах")
void reverse_normalString_returnsReversed() {
assertEquals("табА", StringUtils.reverse("Абат"));
}
@Test
@DisplayName("Хоосон мөр урвуулах")
void reverse_emptyString_returnsEmpty() {
assertEquals("", StringUtils.reverse(""));
}
@Test
@DisplayName("null оруулахад exception үүсэх")
void reverse_null_throwsException() {
assertThrows(IllegalArgumentException.class, () -> {
StringUtils.reverse(null);
});
}
// === isPalindrome() тестүүд ===
@Test
@DisplayName("'madam' нь palindrome")
void isPalindrome_madam_returnsTrue() {
assertTrue(StringUtils.isPalindrome("madam"));
}
@Test
@DisplayName("'hello' нь palindrome биш")
void isPalindrome_hello_returnsFalse() {
assertFalse(StringUtils.isPalindrome("hello"));
}
@Test
@DisplayName("Хоосон мөр palindrome мөн")
void isPalindrome_empty_returnsTrue() {
assertTrue(StringUtils.isPalindrome(""));
}
@Test
@DisplayName("Зайтай palindrome шалгах")
void isPalindrome_withSpaces_returnsTrue() {
assertTrue(StringUtils.isPalindrome("A man a plan a canal Panama"));
}
// === countWords() тестүүд ===
@Test
@DisplayName("3 үгтэй мөрийн үг тоолох")
void countWords_threeWords_returns3() {
assertEquals(3, StringUtils.countWords("Сайн байна уу"));
}
@Test
@DisplayName("Хоосон мөрийн үг тоолох")
void countWords_empty_returns0() {
assertEquals(0, StringUtils.countWords(""));
}
@Test
@DisplayName("null мөрийн үг тоолох")
void countWords_null_returns0() {
assertEquals(0, StringUtils.countWords(null));
}
// === capitalize() тестүүд ===
@Test
@DisplayName("Эхний үсгийг том болгох")
void capitalize_normal_returnsCapitalized() {
assertEquals("Hello", StringUtils.capitalize("hello"));
}
@Test
@DisplayName("Хоосон мөр capitalize")
void capitalize_empty_returnsEmpty() {
assertEquals("", StringUtils.capitalize(""));
}
}
Алхам 5: Eclipse дээр тестийг ажиллуулна:
StringUtilsTestкласс дээр баруун товч → Run As → JUnit Test дарна- Бүх тест ногоон (✅) байх ёстой
3.3 Лаб 2: Хил заагийн шинжилгээ — Дүнгийн баталгаажуулалт
Даалгавар: Оюутны дүнг 0-100 хооронд шалгаж, үсгэн үнэлгээ (A-F) буцаах системийг тестлэх.
// ===== GradeCalculator.java =====
public class GradeCalculator {
public String getGrade(int score) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("Дүн 0-100 хооронд байх ёстой. Оруулсан: " + score);
}
if (score >= 90) return "A"; // 90-100
if (score >= 80) return "B"; // 80-89
if (score >= 70) return "C"; // 70-79
if (score >= 60) return "D"; // 60-69
return "F"; // 0-59
}
public boolean isPassing(int score) {
String grade = getGrade(score);
return !grade.equals("F"); // F биш бол тэнцсэн
}
}
// ===== GradeCalculatorTest.java — Хил заагийн тест =====
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
class GradeCalculatorTest {
private GradeCalculator calculator;
@BeforeEach
void setUp() {
calculator = new GradeCalculator();
}
// === Хил заагийн тестүүд (Boundary Value Analysis) ===
@Test
@DisplayName("Хилийн утга: 0 → F")
void getGrade_score0_returnsF() {
assertEquals("F", calculator.getGrade(0));
}
@Test
@DisplayName("Хилийн утга: 59 → F")
void getGrade_score59_returnsF() {
assertEquals("F", calculator.getGrade(59));
}
@Test
@DisplayName("Хилийн утга: 60 → D")
void getGrade_score60_returnsD() {
assertEquals("D", calculator.getGrade(60));
}
@Test
@DisplayName("Хилийн утга: 69 → D")
void getGrade_score69_returnsD() {
assertEquals("D", calculator.getGrade(69));
}
@Test
@DisplayName("Хилийн утга: 70 → C")
void getGrade_score70_returnsC() {
assertEquals("C", calculator.getGrade(70));
}
@Test
@DisplayName("Хилийн утга: 79 → C")
void getGrade_score79_returnsC() {
assertEquals("C", calculator.getGrade(79));
}
@Test
@DisplayName("Хилийн утга: 80 → B")
void getGrade_score80_returnsB() {
assertEquals("B", calculator.getGrade(80));
}
@Test
@DisplayName("Хилийн утга: 89 → B")
void getGrade_score89_returnsB() {
assertEquals("B", calculator.getGrade(89));
}
@Test
@DisplayName("Хилийн утга: 90 → A")
void getGrade_score90_returnsA() {
assertEquals("A", calculator.getGrade(90));
}
@Test
@DisplayName("Хилийн утга: 100 → A")
void getGrade_score100_returnsA() {
assertEquals("A", calculator.getGrade(100));
}
// === Exception тестүүд ===
@Test
@DisplayName("Сөрөг дүн → Exception")
void getGrade_negativeScore_throwsException() {
assertThrows(IllegalArgumentException.class, () -> {
calculator.getGrade(-1);
});
}
@Test
@DisplayName("101 дүн → Exception")
void getGrade_score101_throwsException() {
assertThrows(IllegalArgumentException.class, () -> {
calculator.getGrade(101);
});
}
// === Параметрчилсэн тест (олон утгаар нэг дор тестлэх) ===
@ParameterizedTest
@DisplayName("Олон дүнгээр тестлэх")
@CsvSource({
"0, F", "30, F", "59, F",
"60, D", "65, D", "69, D",
"70, C", "75, C", "79, C",
"80, B", "85, B", "89, B",
"90, A", "95, A", "100, A"
})
void getGrade_variousScores_returnsCorrectGrade(int score, String expectedGrade) {
assertEquals(expectedGrade, calculator.getGrade(score));
}
// === isPassing() тест ===
@ParameterizedTest
@DisplayName("Тэнцсэн дүнгүүд")
@ValueSource(ints = {60, 70, 80, 90, 100})
void isPassing_passingScores_returnsTrue(int score) {
assertTrue(calculator.isPassing(score));
}
@ParameterizedTest
@DisplayName("Тэнцээгүй дүнгүүд")
@ValueSource(ints = {0, 30, 59})
void isPassing_failingScores_returnsFalse(int score) {
assertFalse(calculator.isPassing(score));
}
}
3.4 Лаб 3: TDD аргаар Password Validator хөгжүүлэх
Даалгавар: Нууц үгийн хүчтэй байдлыг шалгах PasswordValidator классыг TDD аргаар бичих.
Шаардлага:
- Нууц үг дор хаяж 8 тэмдэгттэй
- Дор хаяж 1 том үсэг
- Дор хаяж 1 жижиг үсэг
- Дор хаяж 1 тоо
- Дор хаяж 1 тусгай тэмдэгт (!@#$%^&*)
Алхам 1 — 🔴 RED: Тестийг эхлээд бичнэ
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
class PasswordValidatorTest {
private PasswordValidator validator = new PasswordValidator();
@Test
@DisplayName("null нууц үг → false")
void validate_null_returnsFalse() {
assertFalse(validator.isValid(null));
}
@Test
@DisplayName("Хоосон нууц үг → false")
void validate_empty_returnsFalse() {
assertFalse(validator.isValid(""));
}
@Test
@DisplayName("7 тэмдэгт → богино → false")
void validate_tooShort_returnsFalse() {
assertFalse(validator.isValid("Ab1!xyz")); // 7 тэмдэгт
}
@Test
@DisplayName("Том үсэггүй → false")
void validate_noUpperCase_returnsFalse() {
assertFalse(validator.isValid("abcdef1!"));
}
@Test
@DisplayName("Жижиг үсэггүй → false")
void validate_noLowerCase_returnsFalse() {
assertFalse(validator.isValid("ABCDEF1!"));
}
@Test
@DisplayName("Тоогүй → false")
void validate_noDigit_returnsFalse() {
assertFalse(validator.isValid("Abcdefg!"));
}
@Test
@DisplayName("Тусгай тэмдэгтгүй → false")
void validate_noSpecialChar_returnsFalse() {
assertFalse(validator.isValid("Abcdefg1"));
}
@Test
@DisplayName("Бүх шаардлага хангасан → true")
void validate_validPassword_returnsTrue() {
assertTrue(validator.isValid("MyPass1!"));
}
@ParameterizedTest
@DisplayName("Хүчтэй нууц үгүүд")
@ValueSource(strings = {"Hello@123", "Str0ng!Pass", "Test#2024x"})
void validate_strongPasswords_returnTrue(String password) {
assertTrue(validator.isValid(password));
}
}
Алхам 2 — 🟢 GREEN: Тестийг дамжуулах кодыг бичнэ
public class PasswordValidator {
public boolean isValid(String password) {
// null эсвэл хоосон → буруу
if (password == null || password.isEmpty()) {
return false;
}
// 8-аас бага тэмдэгт → буруу
if (password.length() < 8) {
return false;
}
boolean hasUpper = false; // Том үсэг
boolean hasLower = false; // Жижиг үсэг
boolean hasDigit = false; // Тоо
boolean hasSpecial = false; // Тусгай тэмдэгт
for (char c : password.toCharArray()) {
if (Character.isUpperCase(c)) hasUpper = true;
else if (Character.isLowerCase(c)) hasLower = true;
else if (Character.isDigit(c)) hasDigit = true;
else hasSpecial = true;
}
return hasUpper && hasLower && hasDigit && hasSpecial;
}
// Нууц үгийн хүч тооцоолох (нэмэлт)
public String getStrength(String password) {
if (!isValid(password)) return "Сул";
if (password.length() >= 12) return "Хүчтэй";
return "Дунд";
}
}
Алхам 3 — 🔵 REFACTOR: Тест бүгд ногоон → Код цэвэрлэх
Бүх тест ажиллуулж, бүгд ногоон (✅) болсон эсэхийг шалгана. Шаардлагатай бол кодыг цэвэрлэнэ.
3.5 Лаб 4: Mock ашиглах жишээ (Mockito)
Даалгавар: Имэйл илгээх системийг Mock ашиглан тестлэх.
Алхам 1: pom.xml-д Mockito нэмэх:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
Алхам 2: Код бичих:
// ===== EmailService интерфейс =====
interface EmailService {
boolean sendEmail(String to, String subject, String body);
}
// ===== UserRegistration класс =====
class UserRegistration {
private EmailService emailService;
public UserRegistration(EmailService emailService) {
this.emailService = emailService; // Dependency injection
}
public boolean register(String name, String email) {
if (name == null || name.isEmpty()) return false;
if (email == null || !email.contains("@")) return false;
// Бүртгэл амжилттай → Баталгаажуулах имэйл илгээх
String subject = "Бүртгэл амжилттай!";
String body = "Сайн байна уу, " + name + "! Таны бүртгэл амжилттай.";
emailService.sendEmail(email, subject, body);
return true;
}
}
Алхам 3: Mock тест бичих:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class UserRegistrationTest {
@Test
@DisplayName("Зөв мэдээлэлтэй бүртгэл → имэйл илгээгдэнэ")
void register_validUser_sendsEmail() {
// ARRANGE — Mock EmailService үүсгэх
EmailService mockEmail = mock(EmailService.class);
when(mockEmail.sendEmail(anyString(), anyString(), anyString()))
.thenReturn(true);
UserRegistration reg = new UserRegistration(mockEmail);
// ACT — Бүртгэл хийх
boolean result = reg.register("Бат", "bat@email.com");
// ASSERT — Бүртгэл амжилттай
assertTrue(result);
// VERIFY — Имэйл илгээгдсэн эсэхийг шалгах
verify(mockEmail, times(1)).sendEmail(
eq("bat@email.com"), // Зөв имэйл хаяг руу
eq("Бүртгэл амжилттай!"), // Зөв гарчигтай
contains("Бат") // Нэр агуулсан
);
}
@Test
@DisplayName("Буруу имэйлтэй бүртгэл → имэйл илгээгдэхгүй")
void register_invalidEmail_noEmailSent() {
EmailService mockEmail = mock(EmailService.class);
UserRegistration reg = new UserRegistration(mockEmail);
boolean result = reg.register("Бат", "invalid-email");
assertFalse(result);
// Имэйл огт дуудагдаагүй байх ёстой
verify(mockEmail, never()).sendEmail(anyString(), anyString(), anyString());
}
@Test
@DisplayName("Нэр хоосон → бүртгэл амжилтгүй")
void register_emptyName_returnsFalse() {
EmailService mockEmail = mock(EmailService.class);
UserRegistration reg = new UserRegistration(mockEmail);
assertFalse(reg.register("", "bat@email.com"));
assertFalse(reg.register(null, "bat@email.com"));
verify(mockEmail, never()).sendEmail(anyString(), anyString(), anyString());
}
}
---
---
# ХЭСЭГ 4: ШАЛГАЛТЫН АСУУЛТ (Knowledge Check — 100 тест)
## Тест 1
**Програм хангамжийн тестчилэлийн гол зорилго юу вэ?**
- A) Код бичих
- B) Алдаа олох, чанар баталгаажуулах
- C) Баримт бичиг бичих
- D) Серверт deploy хийх
**Зөв хариулт: B**
> **Тайлбар:** Тестчилэлийн гол зорилго нь програмын алдааг олох, чанарыг баталгаажуулах, хүлээгдэж буй үр дүнгийн дагуу зөв ажиллаж байгааг батлах.
## Тест 2
**ISTQB-ийн тестчилэлийн суурь зарчмуудаас аль нь ЗӨӨВ вэ?**
- A) Тестчилэл нь алдаагүйг баталдаг
- B) Бүрэн тестчилэл боломжтой
- C) Тестчилэл нь алдаа байгааг харуулдаг, алдаагүйг биш
- D) Тест бичих шаардлагагүй
**Зөв хариулт: C**
> **Тайлбар:** ISTQB зарчим 1: Тестчилэл нь алдаа БАЙГААГ харуулж чадна, гэхдээ алдаа БАЙХГҮЙ гэдгийг батлах чадваргүй.
## Тест 3
**"Бүрэн тестчилэл боломжгүй" (Exhaustive testing is impossible) гэсэн зарчим юу гэсэн үг вэ?**
- A) Тест бичих хэрэггүй
- B) Бүх оролт, бүх нөхцөлийг тестлэх нь бараг боломжгүй
- C) Зөвхөн нэг тест бичэхэд хангалттай
- D) Тест автоматаар бичигддэг
**Зөв хариулт: B**
> **Тайлбар:** Бүх боломжит оролтын хослолуудыг тестлэх нь практикт боломжгүй. Тиймээс эрсдэлд суурилсан тест стратеги ашиглана.
## Тест 4
**"Эрт тестлэх" (Early testing) зарчим юу гэсэн үг вэ?**
- A) Тестийг кодчилол дууссаны дараа хийх
- B) Тестийг шаардлага, дизайны шатнаас эхлэх
- C) Тестийг хэрэглэгчид хүрсний дараа хийх
- D) Тестийг зөвхөн QA хийх
**Зөв хариулт: B**
> **Тайлбар:** Алдааг эрт олох тусмаа засах зардал бага. Тестчилэлийг кодчилолоос өмнө (шаардлага, дизайны шатнаас) эхлэх нь чухал.
## Тест 5
**"Алдааны бөөгнөрөл" (Defect clustering) зарчим юу гэсэн үг вэ?**
- A) Бүх модульд алдаа ижил тархдаг
- B) Алдааны 80% нь кодын 20%-д байдаг
- C) Алдаа хэзээ ч олдохгүй
- D) Зөвхөн шинэ кодонд алдаа байдаг
**Зөв хариулт: B**
> **Тайлбар:** Парето зарчим (80/20). Алдааны дийлэнх нь кодын нарийн төвөгтэй, олон удаа өөрчлөгдсөн цөөн хэсэгт бөөгнөрдөг.
## Тест 6
**Unit Testing гэж юу вэ?**
- A) Бүхэл системийг шалгах
- B) Кодын хамгийн жижиг нэгжийг (метод, функц) тусад нь шалгах
- C) Хэрэглэгчийн сэтгэл ханамжийг шалгах
- D) Серверийн ачааллыг шалгах
**Зөв хариулт: B**
> **Тайлбар:** Unit Testing нь кодын хамгийн жижиг нэгжийг (метод, функц) ТУСАД НЬ шалгадаг. Хамгийн хурдан, хамгийн олон, хамгийн хямд тест.
## Тест 7
**Integration Testing гэж юу вэ?**
- A) Нэг методыг тестлэх
- B) Олон модуль нэгдэж зөв ажиллаж байгаа эсэхийг шалгах
- C) Хэрэглэгчийн интерфейсийг тестлэх
- D) Аюулгүй байдлыг шалгах
**Зөв хариулт: B**
> **Тайлбар:** Integration Testing нь олон модуль / компонент НЭГДЭЖ зөв ажиллаж байгаа эсэхийг шалгадаг. Модулиудын хоорондын холболтыг тестлэнэ.
## Тест 8
**Тестийн пирамидын хамгийн доод түвшинд юу байдаг вэ?**
- A) E2E тест
- B) Integration тест
- C) Unit тест
- D) Performance тест
**Зөв хариулт: C**
> **Тайлбар:** Тестийн пирамид: Доод → Unit (маш олон, хурдан), Дунд → Integration (дунд зэрэг), Дээд → E2E (цөөн, удаан).
## Тест 9
**Black-Box Testing гэж юу вэ?**
- A) Кодын дотоод бүтцийг мэдэж тестлэх
- B) Кодын дотоод бүтцийг мэдэхгүйгээр оролт → гаралтыг шалгах
- C) Зөвхөн UI тестлэх
- D) Аюулгүй байдал тестлэх
**Зөв хариулт: B**
> **Тайлбар:** Black-Box = Хар хайрцаг. Дотор нь юу байгааг мэдэхгүйгээр зөвхөн оролт өгч, гаралтыг шалгана. Вендинг машин шиг.
## Тест 10
**White-Box Testing гэж юу вэ?**
- A) Кодын дотоод бүтцийг мэдэхгүйгээр тестлэх
- B) Кодын дотоод бүтцийг мэдэж бүх замналуудыг шалгах
- C) Зөвхөн гадаад оролтыг шалгах
- D) Хэрэглэгчийн тест
**Зөв хариулт: B**
> **Тайлбар:** White-Box = Цагаан хайрцаг. Кодын дотоод бүтцийг мэдэж, бүх салаалт, замналуудыг тестлэнэ. Машины механик мотор задалж шалгах шиг.
## Тест 11
**Equivalence Partitioning гэж юу вэ?**
- A) Кодыг олон хэсэгт хуваах
- B) Оролтыг ижил зан төлөвтэй бүлгүүдэд хуваах
- C) Тестийн нэрийг тодорхойлох
- D) Exception шалгах
**Зөв хариулт: B**
> **Тайлбар:** Equivalence Partitioning нь оролтыг ижил зан төлөвтэй бүлгүүдэд хуваана. Бүлэг бүрээс нэг утга тестлэхэд хангалттай — тестийн тоог багасгана.
## Тест 12
**Boundary Value Analysis гэж юу вэ?**
- A) Бүх утгыг тестлэх
- B) Хилийн утгууд дээр алдаа их гардаг тул хилийн утгуудыг тестлэх
- C) Зөвхөн дунд утгыг тестлэх
- D) Сөрөг утгыг тестлэх
**Зөв хариулт: B**
> **Тайлбар:** Хилийн утгууд дээр алдаа хамгийн их гардаг. Жишээ: 18-65 насны хүрээнд 17, 18, 19, 64, 65, 66 утгуудыг тестлэх.
## Тест 13
**TDD гэж юу вэ?**
- A) Тест бичихгүйгээр код бичих
- B) Тестийг эхлээд бичиж, дараа нь кодыг бичих
- C) Код бичсний дараа тест бичих
- D) Зөвхөн UI тест бичих
**Зөв хариулт: B**
> **Тайлбар:** TDD = Test-Driven Development. "Тестээ ЭХЛЭЭД бич, дараа нь кодоо бич." Red-Green-Refactor цикл.
## Тест 14
**TDD-ийн Red-Green-Refactor цикл ямар дарааллтай вэ?**
- A) Код бич → Тест бич → Засвар
- B) Тест бич (fail) → Код бич (pass) → Код цэвэрлэ
- C) Засвар → Тест → Код
- D) Deploy → Тест → Засвар
**Зөв хариулт: B**
> **Тайлбар:** 🔴 RED: Тест бичих (fail) → 🟢 GREEN: Хамгийн бага кодыг бичиж тестийг дамжуулах → 🔵 REFACTOR: Кодыг цэвэрлэх.
## Тест 15
**JUnit 5-д `@Test` аннотаци юу хийдэг вэ?**
- A) Класс үүсгэх
- B) Метод нь тест гэдгийг JUnit-д заах
- C) Тестийг хаах
- D) Exception шалгах
**Зөв хариулт: B**
> **Тайлбар:** `@Test` аннотаци нь тухайн метод тест метод гэдгийг JUnit framework-д зааж өгдөг. JUnit тэр методыг автоматаар ажиллуулна.
## Тест 16
**`assertEquals(expected, actual)` юу хийдэг вэ?**
- A) Хоёр утгыг ялгаатай эсэхийг шалгах
- B) Хоёр утгыг тэнцүү эсэхийг шалгах
- C) Объект null эсэхийг шалгах
- D) Exception шалгах
**Зөв хариулт: B**
> **Тайлбар:** `assertEquals(expected, actual)` нь хүлээгдэж буй утга (expected) ба бодит утга (actual) ТЭНЦҮҮ эсэхийг шалгана. Тэнцүү бол тест pass, үгүй бол fail.
## Тест 17
**`assertThrows` юу хийдэг вэ?**
- A) Тестийг давтах
- B) Тодорхой exception үүсгэж байгаа эсэхийг шалгах
- C) Тестийн нэр тодорхойлох
- D) Тестийг хаах
**Зөв хариулт: B**
> **Тайлбар:** `assertThrows(ExceptionClass.class, () -> { ... })` нь тодорхой exception ҮҮСГЭЖ байгаа эсэхийг шалгадаг. Алдааны боловсруулалтыг тестлэхэд ашигладаг.
## Тест 18
**`@BeforeEach` аннотаци юу хийдэг вэ?**
- A) Бүх тестийн дараа 1 удаа ажиллах
- B) Тест бүрийн ӨМНӨ ажиллах (setup)
- C) Тестийг хаах
- D) Тестийн нэр тодорхойлох
**Зөв хариулт: B**
> **Тайлбар:** `@BeforeEach` нь тест бүрийн ӨМНӨ ажиллана — тестийн бэлтгэл (fixture) хийхэд ашиглана. Жишээ: шинэ объект үүсгэх.
## Тест 19
**`@ParameterizedTest` юу хийдэг вэ?**
- A) Тестийг хаах
- B) Нэг тестийг олон өөр утгаар давтан ажиллуулах
- C) Тестийн нэр тодорхойлох
- D) Exception шалгах
**Зөв хариулт: B**
> **Тайлбар:** `@ParameterizedTest` нь нэг тестийг олон өөр утгаар (параметрээр) давтан ажиллуулна. Код давтамж багасгаж, олон тохиолдлыг нэг тестээр хамарна.
## Тест 20
**Code Coverage гэж юу вэ?**
- A) Хэдэн тест бичсэн бэ
- B) Тестээр кодын хэдэн хувь хамрагдсан бэ
- C) Хэдэн алдаа олдсон бэ
- D) Хэдэн хэрэглэгч ашигласан бэ
**Зөв хариулт: B**
> **Тайлбар:** Code Coverage нь тестээр кодын хэдэн хувь хамрагдсан бэ гэдгийг хэмждэг. Жишээ: 100 мөрнөөс 80-ыг тест ажиллуулсан → 80% coverage.
## Тест 21
**Statement Coverage гэж юу вэ?**
- A) Бүх метод дуудагдсан эсэх
- B) Кодын мөр бүр дор хаяж 1 удаа ажиллаж байгааг шалгах
- C) Бүх салаалт тестлэгдсэн эсэх
- D) Бүх exception шалгагдсан эсэх
**Зөв хариулт: B**
> **Тайлбар:** Statement Coverage нь кодын мөр/мэдэгдэл (statement) бүр дор хаяж 1 удаа ажиллаж байгааг шалгана.
## Тест 22
**Branch Coverage гэж юу вэ?**
- A) Бүх мөр ажиллаж байгааг шалгах
- B) if/else бүр TRUE ба FALSE чиглэлд тестлэгдсэн эсэхийг шалгах
- C) Бүх метод дуудагдсан эсэх
- D) Бүх класс ачаалагдсан эсэх
**Зөв хариулт: B**
> **Тайлбар:** Branch Coverage нь кодын бүх салаалтын (if/else, switch) TRUE ба FALSE замыг тестлэгдсэн эсэхийг шалгана. Statement Coverage-ээс илүү нарийн.
## Тест 23
**100% Code Coverage нь юу гэсэн үг вэ?**
- A) Програм алдаагүй
- B) Кодын бүх мөр тестээр ажиллаж байгаа, гэхдээ алдаагүй гэсэн үг биш
- C) Тест бичих шаардлагагүй
- D) Програм бэлэн
**Зөв хариулт: B**
> **Тайлбар:** 100% coverage ≠ алдаагүй! Бүх мөр ажилласан ч тест нь ЗӨӨВ ЗҮЙЛИЙГ шалгаж байгаа эсэх (test quality) чухал. Логик алдаа coverage-д харагдахгүй.
## Тест 24
**AAA загвар (Arrange-Act-Assert) юу вэ?**
- A) Тестийн фреймворк
- B) Тестийн бүтцийн загвар: Бэлтгэх → Үйлдэл хийх → Шалгах
- C) Тестийн нэрлэх дүрэм
- D) Алдааны төрөл
**Зөв хариулт: B**
> **Тайлбар:** AAA: Arrange (бэлтгэх — объект үүсгэх), Act (үйлдэл хийх — метод дуудах), Assert (шалгах — үр дүн зөв эсэх). Тест бүрийг энэ бүтцээр бичнэ.
## Тест 25
**FIRST зарчмын "F" юу гэсэн үг вэ?**
- A) Functional
- B) Fast — хурдан
- C) Final
- D) First
**Зөв хариулт: B**
> **Тайлбар:** F = Fast. Тест маш ХУРДАН ажиллах ёстой. Удаан тестийг хөгжүүлэгчид ажиллуулахаас залхуурдаг → Алдаа олдохгүй.
## Тест 26
**FIRST зарчмын "I" юу гэсэн үг вэ?**
- A) Integration
- B) Independent — бие даасан
- C) Important
- D) Interface
**Зөв хариулт: B**
> **Тайлбар:** I = Independent. Тестүүд бие биенээсээ ХАМААРАЛГҮЙ байх ёстой. Нэг тест fail болсноор бусад тест fail болох ёсгүй.
## Тест 27
**FIRST зарчмын "R" юу гэсэн үг вэ?**
- A) Reliable
- B) Repeatable — давтагдах
- C) Recursive
- D) Refactored
**Зөв хариулт: B**
> **Тайлбар:** R = Repeatable. Хэзээ ч, хаана ч ажиллуулсан ИЖИЛ ҮР ДҮН гарах ёстой. Орчноос хамаарч зарим үед pass, зарим үед fail болж болохгүй.
## Тест 28
**Mock гэж юу вэ?**
- A) Бодит мэдээллийн сан
- B) Бодит объектын оронд ашигладаг хиймэл объект
- C) Тестийн фреймворк
- D) Тестийн нэрлэх дүрэм
**Зөв хариулт: B**
> **Тайлбар:** Mock нь бодит объектын оронд ашигладаг хиймэл объект. Бодит мэдээллийн сан, имэйл сервер зэргийг хиймлээр орлуулж тестлэхэд ашигладаг.
## Тест 29
**Stub ба Mock-ийн ялгаа юу вэ?**
- A) Ялгаагүй
- B) Stub нь бэлэн хариу буцаадаг, Mock нь зан төлөвийг (дуудагдсан эсэх) шалгадаг
- C) Mock нь бодит объект, Stub нь хиймэл
- D) Stub нь илүү нарийн
**Зөв хариулт: B**
> **Тайлбар:** Stub = бэлэн хариу буцаах (return true). Mock = зан төлөвийг шалгах (метод дуудагдсан уу? хэдэн удаа?).
## Тест 30
**Regression Testing гэж юу вэ?**
- A) Шинэ функц тестлэх
- B) Шинэ код хуучин функцийг эвдсэн эсэхийг шалгах
- C) Серверийн ачааллыг шалгах
- D) UI тестлэх
**Зөв хариулт: B**
> **Тайлбар:** Regression Testing нь шинэ код нэмэх, засвар хийхэд хуучин функцүүд зөв ажилласаар байгаа эсэхийг шалгадаг. Автоматжуулсан тест маш чухал.
## Тест 31
**Smoke Testing гэж юу вэ?**
- A) Бүх зүйлийг нарийвчлан тестлэх
- B) Системийн суурь функцүүд ажиллаж байна уу гэдгийг хурдан шалгах
- C) Серверийн утаа шалгах
- D) Аюулгүй байдлыг шалгах
**Зөв хариулт: B**
> **Тайлбар:** Smoke Test = "Утааны тест". Системийн хамгийн чухал суурь функцүүд ажиллаж байна уу гэдгийг хурдан шалгана. Build-ийн дараа эхлээд smoke test ажиллуулна.
## Тест 32
**Acceptance Testing-ийн зорилго юу вэ?**
- A) Кодын бүтцийг шалгах
- B) Хэрэглэгч / захиалагч системийг хүлээн авах боломжтой эсэхийг шалгах
- C) Хурдыг шалгах
- D) Аюулгүй байдлыг шалгах
**Зөв хариулт: B**
> **Тайлбар:** Acceptance Testing нь хэрэглэгч/захиалагч системийг шаардлагын дагуу хүлээн авах боломжтой эсэхийг шалгадаг. Alpha, Beta, UAT тест орно.
## Тест 33
**Performance Testing гэж юу вэ?**
- A) Функц зөв ажиллаж байгааг шалгах
- B) Системийн хурд, хариу өгөх хугацааг шалгах
- C) Кодын бүтцийг шалгах
- D) Алдааг олох
**Зөв хариулт: B**
> **Тайлбар:** Performance Testing нь системийн хурд (response time), дамжуулах чадвар (throughput), нөөц ашиглалтыг (CPU, RAM) шалгадаг.
## Тест 34
**Load Testing ба Stress Testing-ийн ялгаа юу вэ?**
- A) Ялгаагүй
- B) Load нь хүлээгдэж буй ачааллыг, Stress нь хязгаарын ачааллыг шалгадаг
- C) Stress нь илүү хялбар
- D) Load нь аюулгүй байдал шалгадаг
**Зөв хариулт: B**
> **Тайлбар:** Load Testing: хүлээгдэж буй ачаалал дор (1000 хэрэглэгч) ажиллагааг шалгана. Stress Testing: хязгаарын ачаалал (10000+ хэрэглэгч) дор систем яаж эвддэгийг шалгана.
## Тест 35
**Security Testing гэж юу вэ?**
- A) Хурдыг шалгах
- B) Системийн аюулгүй байдлыг, эмзэг цэгүүдийг шалгах
- C) UI дизайн шалгах
- D) Кодын хамралт шалгах
**Зөв хариулт: B**
> **Тайлбар:** Security Testing нь системийн аюулгүй байдлыг шалгадаг: SQL injection, XSS, authentication эмзэг цэгүүд байна уу гэдгийг тестлэнэ.
## Тест 36
**Grey-Box Testing гэж юу вэ?**
- A) Зөвхөн гадаад тест
- B) Black-Box ба White-Box-ийн хослол
- C) Зөвхөн дотоод тест
- D) Аюулгүй байдлын тест
**Зөв хариулт: B**
> **Тайлбар:** Grey-Box = Саарал хайрцаг. Дотоод бүтцийн ЗАРИМ мэдлэгтэй байж, гадаад оролт → гаралтыг тестлэх. Хар + Цагаан хослуулсан.
## Тест 37
**Тестийн тохиолдлын тоог хамгийн их багасгах техник аль нь вэ?**
- A) Path Coverage
- B) Equivalence Partitioning
- C) Branch Coverage
- D) Statement Coverage
**Зөв хариулт: B**
> **Тайлбар:** Equivalence Partitioning нь оролтыг бүлэглэж, бүлэг бүрээс зөвхөн нэг утга тестлэдэг → Тестийн тоог хамгийн их багасгана.
## Тест 38
**Дараах кодыг 100% Statement Coverage хийхэд хамгийн бага хэдэн тест хэрэгтэй вэ?**
```java
if (x > 0) { return "positive"; }
else { return "non-positive"; }
- A) 1
- B) 2
- C) 3
- D) 4
Зөв хариулт: B
Тайлбар: 2 тест: x=5 (positive замыг), x=-1 (non-positive замыг) → Бүх мэдэгдэл ажиллана.
Тест 39
Дараах кодыг 100% Branch Coverage хийхэд хамгийн бага хэдэн тест хэрэгтэй вэ?
if (a > 0 && b > 0) { result = "both positive"; }
else { result = "not both positive"; }
- A) 1
- B) 2
- C) 3
- D) 4
Зөв хариулт: B
Тайлбар: 2 тест: (a=1, b=1) → TRUE зам, (a=-1, b=1) → FALSE зам. Branch Coverage = бүх салаалтын TRUE/FALSE замыг тестлэх.
Тест 40
assertTrue(condition) юу хийдэг вэ?
- A) condition false эсэхийг шалгах
- B) condition TRUE эсэхийг шалгах
- C) condition null эсэхийг шалгах
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
assertTrue(condition)нь condition нь TRUE байгаа эсэхийг шалгана. TRUE бол тест pass, FALSE бол fail.
Тест 41
assertNull(object) юу хийдэг вэ?
- A) Объект null биш эсэхийг шалгах
- B) Объект NULL эсэхийг шалгах
- C) Хоёр объект тэнцүү эсэхийг шалгах
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
assertNull(object)нь объект null байгаа эсэхийг шалгана. null бол pass, null биш бол fail.assertNotNull()нь эсрэгээрээ.
Тест 42
@DisplayName аннотаци юу хийдэг вэ?
- A) Тестийг хаах
- B) Тестийн нэр/тайлбарыг тодорхойлох
- C) Тестийн дарааллыг тодорхойлох
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
@DisplayName("Мөнгө нэмэхэд үлдэгдэл нэмэгдэх")— Тестийн нэрийг хүн уншихад ойлгомжтой болгож тодорхойлно. Тестийн тайлан дээр харагдана.
Тест 43
@Disabled аннотаци юу хийдэг вэ?
- A) Тестийг устгах
- B) Тестийг түр хаах (skip)
- C) Тестийг давтах
- D) Тестийн нэр тодорхойлох
Зөв хариулт: B
Тайлбар:
@Disabledнь тестийг түр хаадаг — ажиллуулдаггүй. Засвар хийж байх үед эсвэл тодорхой шалтгаанаар тестийг түр алгасах хэрэгтэй үед ашиглана.
Тест 44
@BeforeAll ба @BeforeEach-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B)
@BeforeAllбүх тестийн өмнө 1 удаа,@BeforeEachтест бүрийн өмнө ажиллана - C)
@BeforeEachнь хурдан - D)
@BeforeAllнь тест бүрийн дараа ажиллана
Зөв хариулт: B
Тайлбар:
@BeforeAll= Бүх тестийн өмнө НЭХЭН удаа (static method).@BeforeEach= ТЕСТ БҮРИЙН өмнө. Жишээ: DB холболт нэг удаа, шинэ объект тест бүрд.
Тест 45
"Нэг тест — нэг зүйл шалгах" зарчим юу гэсэн үг вэ?
- A) Нэг тест файлд нэг тест бичих
- B) Тест бүр зөвхөн нэг зан төлөвийг шалгах ёстой
- C) Зөвхөн нэг класс тестлэх
- D) Нэг assert ашиглах
Зөв хариулт: B
Тайлбар: Тест бүр зөвхөн нэг зан төлөвийг шалгах ёстой. Тест fail болоход яг юу буруу болсон нь тодорхой байна. Олон зүйл нэг тестэд хольвол алдааг олоход хэцүү.
Тест 46
Тестийн нэрлэх сайн загвар аль нь вэ?
- A) test1, test2, test3
- B) methodName_condition_expectedResult
- C) a, b, c
- D) myTest
Зөв хариулт: B
Тайлбар:
add_twoPositiveNumbers_returnsSum— Ямар метод, ямар нөхцөлд, ямар үр дүн хүлээж байгааг тодорхой заасан. Тест fail болоход нэрнээс нь юу буруу болсон ойлгогдоно.
Тест 47
Integration Testing-ийн "Big Bang" арга гэж юу вэ?
- A) Нэг нэгээр нь нэгтгэх
- B) Бүх модулийг нэг дор нэгтгэж тестлэх
- C) Дээрээс доош нэгтгэх
- D) Доороос дээш нэгтгэх
Зөв хариулт: B
Тайлбар: Big Bang: Бүх модулийг нэг дор нэгтгэж тестлэнэ. Алдаа гарвал аль модулийнх болохыг олоход хэцүү — жижиг төслүүдэд тохиромжтой.
Тест 48
Integration Testing-ийн "Top-Down" арга гэж юу вэ?
- A) Доороос дээш нэгтгэх
- B) Дээд түвшний модулиас эхлэн доош нэгтгэж тестлэх
- C) Бүх модулийг нэг дор тестлэх
- D) Зөвхөн нэг модуль тестлэх
Зөв хариулт: B
Тайлбар: Top-Down: Дээд түвшний (main) модулиас эхлэн доод түвшний модулиуд руу нэг нэгээр нь нэгтгэнэ. Доод модулийг Stub-аар орлуулна.
Тест 49
Alpha Testing ба Beta Testing-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Alpha нь хөгжүүлэгч байгууллагын дотор, Beta нь бодит хэрэглэгчдэд тарааж шалгуулах
- C) Beta нь эхлээд, Alpha нь дараа
- D) Alpha нь автоматжуулсан
Зөв хариулт: B
Тайлбар: Alpha: Хөгжүүлэгч байгууллагын дотоод орчинд хийх тест. Beta: Бодит хэрэглэгчдэд тарааж, бодит орчинд шалгуулах тест.
Тест 50
Decision Table техник юу хийдэг вэ?
- A) Кодын бүтцийг задлах
- B) Олон нөхцөлийн хослолуудыг хүснэгтээр тестлэх
- C) Хилийн утга олох
- D) Алдаа засах
Зөв хариулт: B
Тайлбар: Decision Table нь олон нөхцөлийн (if-else) хослолуудыг хүснэгтээр зохион байгуулж, бүх хослолыг тестлэх боломж олгодог.
Тест 51
Test Fixture гэж юу вэ?
- A) Тестийн фреймворк
- B) Тест ажиллуулахад шаардлагатай бэлтгэлийн өгөгдөл, объектууд
- C) Тестийн нэр
- D) Exception шалгах арга
Зөв хариулт: B
Тайлбар: Test Fixture нь тест ажиллуулахад хэрэгтэй бэлтгэлийн объектууд, өгөгдөл. @BeforeEach-д үүсгэгддэг. Жишээ:
account = new BankAccount("Бат", 10000);
Тест 52
Mockito дахь verify() метод юу хийдэг вэ?
- A) Объект үүсгэх
- B) Mock объектын метод дуудагдсан эсэхийг баталгаажуулах
- C) Тестийг давтах
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
verify(mockEmail, times(1)).sendEmail(...)— Mock объектынsendEmailметод яг 1 удаа дуудагдсан эсэхийг шалгана.
Тест 53
Mockito дахь when().thenReturn() юу хийдэг вэ?
- A) Тест бичих
- B) Mock объектын метод дуудагдахад буцаах утгыг тодорхойлох
- C) Exception шалгах
- D) Тестийн нэр тодорхойлох
Зөв хариулт: B
Тайлбар:
when(mockObj.method()).thenReturn(value)— Mock объектын тодорхой метод дуудагдахад ямар утга буцаахыг тодорхойлно. Stub шиг ажилладаг.
Тест 54
Тестийн пирамид дахь E2E (End-to-End) тест юу вэ?
- A) Нэг метод тестлэх
- B) Бүхэл системийг эхнээс нь төгсгөл хүртэл хэрэглэгчийн нүдээр тестлэх
- C) Нэгтгэлийн тест
- D) Кодын хамралт шалгах
Зөв хариулт: B
Тайлбар: E2E = End-to-End. Бүхэл системийг хэрэглэгчийн нүдээр: Нэвтрэх → Бүтээгдэхүүн сонгох → Сагсанд нэмэх → Төлбөр хийх → гэх мэт бүрэн тестлэнэ.
Тест 55
Functional Testing ба Non-Functional Testing-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Functional нь "юу хийдэг"-ийг, Non-Functional нь "яаж хийдэг"-ийг шалгана
- C) Non-Functional нь илүү чухал
- D) Functional нь зөвхөн UI
Зөв хариулт: B
Тайлбар: Functional: Систем ЮУ ХИЙДЭГ-ийг шалгана (нэвтрэлт зөв ажиллаж байна уу?). Non-Functional: Систем ЯАЖЕ ХИЙДЭГ-ийг шалгана (хэр хурдан? аюулгүй юу?).
Тест 56
"Pesticide Paradox" зарчим юу гэсэн үг вэ?
- A) Тест бичих шаардлагагүй
- B) Ижил тестийг давтвал шинэ алдаа олдохгүй
- C) Шинэ тест хэзээ ч ашиггүй
- D) Тест автоматаар бичигддэг
Зөв хариулт: B
Тайлбар: Хортон шавжны эмийг давтвал шавж дасдаг шиг — ижил тестийг давтвал шинэ алдаа олдохгүй. Тестийг байнга шинэчлэх, шинэ тохиолдлууд нэмэх шаардлагатай.
Тест 57
"Absence-of-errors fallacy" зарчим юу гэсэн үг вэ?
- A) Алдаатай програм зөв
- B) Алдаагүй програм ≠ хэрэглэгчийн хэрэгцээг хангасан програм
- C) Тест бичих хэрэггүй
- D) Бүх алдааг олж болно
Зөв хариулт: B
Тайлбар: 0 алдаатай програм ч хэрэглэгчийн ХЭРЭГЦЭЭНД нийцэхгүй байж болно. Тестчилэл нь зөвхөн алдаа олохоос гадна шаардлага хангаж буй эсэхийг шалгах ёстой.
Тест 58
Дараах кодонд тест FAIL болдог. Алдаа юу вэ?
@Test
void testDivide() {
Calculator c = new Calculator();
assertEquals(2, c.divide(10, 3)); // 10 / 3 = ?
}
- A) Кодонд алдаа байхгүй
- B) 10 / 3 = 3 (integer division) байхад 2 гэж хүлээж байна
- C) Calculator класс алга
- D) assertEquals ажиллахгүй
Зөв хариулт: B
Тайлбар: Java-д integer division: 10 / 3 = 3 (бүхэл тоо). Тест 2 гэж хүлээж байгаа тул fail болно. Зөв хүлээгдэх утга: 3.
Тест 59
assertTimeout юу хийдэг вэ?
- A) Тестийг давтах
- B) Тест тодорхой хугацааны дотор дуусах ёстойг шалгах
- C) Тестийн нэр тодорхойлох
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
assertTimeout(Duration.ofSeconds(2), () -> { ... })— Код 2 секундийн дотор дуусах ёстой. Хугацаа хэтэрвэл тест fail.
Тест 60
Test Suite гэж юу вэ?
- A) Нэг тест
- B) Хэд хэдэн test case-ийг бүлэглэсэн цуглуулга
- C) Тестийн фреймворк
- D) Тестийн нэрлэх дүрэм
Зөв хариулт: B
Тайлбар: Test Suite нь хэд хэдэн test case-ийг бүлэглэсэн цуглуулга. Жишээ: BankAccountTest, UserTest, OrderTest → AllTests suite.
Тест 61
Usability Testing гэж юу вэ?
- A) Кодын бүтцийг шалгах
- B) Хэрэглэгчид хэрэглэхэд хялбар эсэхийг шалгах
- C) Хурдыг шалгах
- D) Аюулгүй байдлыг шалгах
Зөв хариулт: B
Тайлбар: Usability Testing нь хэрэглэгчид системийг ХЯЛБАР ашиглаж чадаж байгаа эсэхийг шалгадаг. Хэрэглэгчийн туршлага (UX) сайн уу?
Тест 62
Compatibility Testing гэж юу вэ?
- A) Кодыг оновчлох
- B) Систем өөр өөр орчинд (browser, OS, төхөөрөмж) ажиллаж байгаа эсэхийг шалгах
- C) Хурдыг шалгах
- D) Аюулгүй байдлыг шалгах
Зөв хариулт: B
Тайлбар: Compatibility Testing: Chrome, Firefox, Safari, iOS, Android, Windows, Mac зэрэг өөр өөр орчинд систем зөв ажиллаж байгааг шалгана.
Тест 63
BDD (Behavior-Driven Development) гэж юу вэ?
- A) Зөвхөн код бичих
- B) Хэрэглэгчийн зан төлөвөөс эхлэн тест, код бичих
- C) Тест бичихгүй
- D) Зөвхөн UI тестлэх
Зөв хариулт: B
Тайлбар: BDD = Behavior-Driven Development. Given-When-Then загвараар хэрэглэгчийн зан төлөвийг тодорхойлж, тэр дагуу тест, код бичнэ.
Тест 64
BDD-ийн Given-When-Then загвар юу вэ?
- A) Тестийн фреймворк
- B) Given (өгөгдсөн нөхцөл) → When (үйлдэл) → Then (хүлээгдэх үр дүн)
- C) Кодын бүтэц
- D) Тестийн нэрлэх дүрэм
Зөв хариулт: B
Тайлбар: Given: Дансанд 10000₮ байна. When: 3000₮ авахад. Then: Үлдэгдэл 7000₮ байна. Хэрэглэгчийн хэлээр тестийг тодорхойлно.
Тест 65
Continuous Testing гэж юу вэ?
- A) Тестийг зөвхөн нэг удаа ажиллуулах
- B) CI/CD дамжуулгад код push хийх бүрт тест автоматаар ажиллуулах
- C) Зөвхөн гараар тестлэх
- D) Тест бичихгүй
Зөв хариулт: B
Тайлбар: Continuous Testing нь CI/CD (Continuous Integration / Continuous Delivery) дамжуулгад тестийг автоматаар ажиллуулдаг. Git push → Тест автоматаар ажиллана.
Тест 66
Дараах аль нь тестийн автоматжуулалтын давуу тал вэ?
- A) Удаан ажилладаг
- B) Давтан ажиллуулахад хурдан, найдвартай
- C) Зөвхөн нэг удаа ашиглаж болно
- D) Бүх алдааг олдог
Зөв хариулт: B
Тайлбар: Автоматжуулсан тест давтан ажиллуулахад маш ХУРДАН, НАЙДВАРТАЙ. Гар тест олон удаа давтахад удаан, алдаа гаргаж болно.
Тест 67
@RepeatedTest(5) юу хийдэг вэ?
- A) Тестийг 5 секунд хүлээх
- B) Нэг тестийг 5 удаа давтан ажиллуулах
- C) 5 тест үүсгэх
- D) Тестийг 5 дахь мөрнөөс эхлүүлэх
Зөв хариулт: B
Тайлбар:
@RepeatedTest(5)нь тухайн тестийг 5 удаа давтан ажиллуулна. Random утгатай тест, concurrency тест зэрэгт ашигтай.
Тест 68
@CsvSource юу хийдэг вэ?
- A) CSV файл уншах
- B) Параметрчилсэн тестэд олон утгыг CSV хэлбэрээр дамжуулах
- C) Тестийн нэр тодорхойлох
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
@CsvSource({"90, A", "80, B", "70, C"})— Олон оролт-хүлээгдэх гаралтын хосыг CSV хэлбэрээр параметрчилсэн тестэд дамжуулна.
Тест 69
Тестийн пирамидын дээд хэсэгт ямар тест байдаг вэ?
- A) Unit тест
- B) Integration тест
- C) E2E (End-to-End) тест
- D) Performance тест
Зөв хариулт: C
Тайлбар: Пирамидын дээд = E2E тест (цөөн, удаан, үнэтэй). Дунд = Integration. Доод = Unit (олон, хурдан, хямд).
Тест 70
JUnit 5-д assertArrayEquals юу хийдэг вэ?
- A) Нэг утгыг шалгах
- B) Хоёр массивын элементүүд тэнцүү эсэхийг шалгах
- C) Массив хоосон эсэхийг шалгах
- D) Массив null эсэхийг шалгах
Зөв хариулт: B
Тайлбар:
assertArrayEquals(expected, actual)нь хоёр массивын элемент бүрийг тэнцүү эсэхийг шалгана. Бүх элемент тэнцүү бол pass.
Тест 71
Дараах кодонд ямар тестийн загвар ашиглагдаж байна вэ?
@Test void testDeposit() {
BankAccount account = new BankAccount("Бат", 10000); // ?
account.deposit(5000); // ?
assertEquals(15000, account.getBalance()); // ?
}
- A) Red-Green-Refactor
- B) AAA (Arrange-Act-Assert)
- C) Given-When-Then
- D) FIRST
Зөв хариулт: B
Тайлбар: Arrange: BankAccount үүсгэх. Act: deposit() дуудах. Assert: assertEquals() шалгах. AAA загвар.
Тест 72
Дараах тестийн нэрнээс юу ойлгож болох вэ: withdraw_insufficientBalance_throwsException?
- A) withdraw метод, үлдэгдэл хүрэлцэхгүй үед, exception шалгаж байна
- B) Шинэ данс үүсгэж байна
- C) Мөнгө нэмж байна
- D) Тестийг хааж байна
Зөв хариулт: A
Тайлбар:
methodName_condition_expectedResultзагвар: withdraw (метод), insufficientBalance (нөхцөл), throwsException (хүлээгдэх үр дүн).
Тест 73
Алдааг хөгжүүлэлтийн аль шатанд олох нь ХАМГИЙН ХЯМД вэ?
- A) Дизайн
- B) Кодчилол
- C) Шаардлага тодорхойлолт
- D) Хэрэглэгчид хүрсний дараа
Зөв хариулт: C
Тайлбар: Шаардлагын шатанд алдааг олоход 1× зардал. Хэрэглэгчид хүрсний дараа олоход 100× зардал. Эрт олох = Хямд.
Тест 74
Алдааг хэрэглэгчид хүрсний дараа олоход засах зардал ойролцоогоор хэдэн дахин нэмэгддэг вэ?
- A) 2 дахин
- B) 10 дахин
- C) 50 дахин
- D) 100 дахин
Зөв хариулт: D
Тайлбар: Шаардлагын шатанд 1× байсан бол хэрэглэгчид хүрсний дараа ~100× нэмэгддэг (IBM Systems Sciences Institute).
Тест 75
Тестийн пирамидын unit тест хэдэн хувийг эзэлдэг вэ (ойролцоогоор)?
- A) 10-20%
- B) 30-40%
- C) 50-60%
- D) 70-80%
Зөв хариулт: D
Тайлбар: Тестийн пирамидын 70-80% нь unit тест. Учир нь хамгийн хурдан, хамгийн хямд, хамгийн найдвартай.
Тест 76
JUnit 5-д тест класс public байх шаардлагатай юу?
- A) Заавал public байх ёстой
- B) Public байх шаардлагагүй (package-private хангалттай)
- C) Заавал private байх ёстой
- D) Заавал abstract байх ёстой
Зөв хариулт: B
Тайлбар: JUnit 5-д тест класс, тест метод public байх шаардлагагүй. Package-private (default access) хангалттай. JUnit 4-д public шаардлагатай байсан.
Тест 77
Path Coverage ба Branch Coverage-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Path Coverage нь бүх боломжит замналуудыг, Branch Coverage нь зөвхөн салаалтуудыг хамарна
- C) Branch Coverage нь илүү иж бүрэн
- D) Path Coverage нь хялбар
Зөв хариулт: B
Тайлбар: Path Coverage нь бүх боломжит замналуудыг тестлэнэ → Хамгийн иж бүрэн гэхдээ хамгийн их тест шаардана. Branch Coverage нь зөвхөн салаалтын TRUE/FALSE-ыг хамарна.
Тест 78
Дараах аль нь Black-Box тестийн техник БИШ вэ?
- A) Equivalence Partitioning
- B) Boundary Value Analysis
- C) Statement Coverage
- D) Decision Table
Зөв хариулт: C
Тайлбар: Statement Coverage нь White-Box тестийн техник (кодын дотоод бүтцийг мэддэг). Equivalence Partitioning, Boundary Value, Decision Table нь Black-Box.
Тест 79
Дараах аль нь White-Box тестийн техник БИШ вэ?
- A) Statement Coverage
- B) Branch Coverage
- C) Path Coverage
- D) Equivalence Partitioning
Зөв хариулт: D
Тайлбар: Equivalence Partitioning нь Black-Box техник. Statement, Branch, Path Coverage нь White-Box техникүүд.
Тест 80
ISTQB-ийн 7 суурь зарчмын тоо хэд вэ?
- A) 3
- B) 5
- C) 7
- D) 10
Зөв хариулт: C
Тайлбар: ISTQB 7 зарчим: 1) Алдаа байгааг харуулдаг, 2) Бүрэн тестчилэл боломжгүй, 3) Эрт тестлэх, 4) Алдааны бөөгнөрөл, 5) Pesticide paradox, 6) Контекстаас хамаарна, 7) Absence-of-errors fallacy.
Тест 81
Дараах тест зөв ажиллах уу?
@Test void testNotNull() {
String str = "Hello";
assertNotNull(str);
}
- A) Fail болно
- B) Pass болно
- C) Компайл алдаа
- D) Runtime алдаа
Зөв хариулт: B
Тайлбар:
str = "Hello"нь null биш тулassertNotNull(str)pass болно.
Тест 82
Дараах тест зөв ажиллах уу?
@Test void testEqual() {
assertEquals("hello", "Hello");
}
- A) Pass болно
- B) Fail болно — "hello" ≠ "Hello" (case-sensitive)
- C) Компайл алдаа
- D) Runtime алдаа
Зөв хариулт: B
Тайлбар:
assertEqualsнь case-sensitive. "hello" ≠ "Hello" (жижиг h ≠ том H) тул тест FAIL болно.
Тест 83
Mockito дахь never() юу гэсэн үг вэ?
- A) Метод 1 удаа дуудагдсан
- B) Метод ОГТ дуудагдаагүй байх ёстой
- C) Метод олон удаа дуудагдсан
- D) Mock үүсгэх
Зөв хариулт: B
Тайлбар:
verify(mock, never()).method()— Метод ОГТ ДУУДАГДААГҮЙ байх ёстой. Буруу оролтод имэйл илгээгдэхгүй байх ёстой → never() ашиглана.
Тест 84
Dependency Injection яагаад тестлэхэд тусалдаг вэ?
- A) Код хурдан болдог
- B) Бодит хамаарлыг Mock-оор солиход хялбар болгодог
- C) Тест автоматаар бичигддэг
- D) Компайлер шаарддаг
Зөв хариулт: B
Тайлбар: Dependency Injection: Хамаарлыг гаднаас дамжуулна → Тестэд бодит объектын оронд Mock оруулахад маш хялбар.
new UserService(mockEmailService).
Тест 85
Flaky Test гэж юу вэ?
- A) Үргэлж pass болдог тест
- B) Зарим үед pass, зарим үед fail болдог тогтворгүй тест
- C) Үргэлж fail болдог тест
- D) Тестийн фреймворк
Зөв хариулт: B
Тайлбар: Flaky Test = Тогтворгүй тест. Ижил код дээр зарим үед pass, зарим үед fail. Шалтгаан: timing, race condition, гадаад хамаарал. FIRST-ийн R (Repeatable) зарчмыг зөрчдөг.
Тест 86
Test Double гэж юу вэ?
- A) Тестийг 2 удаа ажиллуулах
- B) Бодит объектыг орлуулж тестэд ашигладаг хиймэл объектуудын нийтлэг нэр
- C) Тестийн фреймворк
- D) Кодын хамралт
Зөв хариулт: B
Тайлбар: Test Double = Тестийн орлуулагч. Mock, Stub, Fake, Spy, Dummy зэрэг бүгдийг нийтлэг нэрээр Test Double гэнэ. Жүжгийн "дублёр" шиг.
Тест 87
Mutation Testing гэж юу вэ?
- A) Кодыг устгах
- B) Кодыг жижиг өөрчлөлт хийж (мутант), тест тэр өөрчлөлтийг олж чадаж байгаа эсэхийг шалгах
- C) Шинэ тест бичих
- D) Тестийн нэр тодорхойлох
Зөв хариулт: B
Тайлбар: Mutation Testing: Кодонд жижиг алдаа (мутант) оруулна (> → <, + → -). Тест олж чадвал "мутант устсан" (killed). Олохгүй бол тест сул.
Тест 88
Дараах аль нь тестийн автоматжуулалтын сул тал вэ?
- A) Хурдан ажилладаг
- B) Анхны суулгалт, бичих зардал өндөр
- C) Найдвартай
- D) Давтан ажиллуулж болно
Зөв хариулт: B
Тайлбар: Тестийн автоматжуулалтын сул тал: Анхны суулгалт, framework сурах, тест бичих ЗАРДАЛ ӨНДӨР. Гэхдээ урт хугацаанд хэмнэлт үнэтэй.
Тест 89
"Тестчилэл нь контекстаас хамаарна" гэсэн зарчим юу гэсэн үг вэ?
- A) Бүх програмыг ижил тестлэнэ
- B) Тестийн стратеги нь програмын төрөл, эрсдэлээс хамаарна
- C) Тестчилэл шаардлагагүй
- D) Зөвхөн unit тест хангалттай
Зөв хариулт: B
Тайлбар: Нисэх онгоцны програм vs мобайл тоглоом → Тестийн стратеги тэс өөр. Програмын төрөл, эрсдэл, чухал ач холбогдлоос хамаарч тест стратеги сонгоно.
Тест 90
Хамгийн зөвлөгддөг Code Coverage түвшин хэд вэ?
- A) 10-20%
- B) 30-50%
- C) 70-85%
- D) 100%
Зөв хариулт: C
Тайлбар: 70-85% нь ихэнх төслийн стандарт. 100% хэтэрхий → тестийн maintenance зардал нэмэгддэг. 100% coverage ≠ алдаагүй гэдгийг санах.
Тест 91
Integration Testing-ийн Bottom-Up арга гэж юу вэ?
- A) Дээрээс доош нэгтгэх
- B) Доод түвшний модулиас эхлэн дээш нэгтгэж тестлэх
- C) Бүх модулийг нэг дор тестлэх
- D) Зөвхөн нэг модуль тестлэх
Зөв хариулт: B
Тайлбар: Bottom-Up: Доод түвшний модулиас (helper, utility) эхлэн дээд түвшин рүү нэг нэгээр нэгтгэнэ. Дээд модулийг Driver-аар орлуулна.
Тест 92
UAT (User Acceptance Testing) гэж юу вэ?
- A) Хөгжүүлэгч хийдэг тест
- B) Захиалагч / эцсийн хэрэглэгч системийг хүлээн авахын өмнө шалгах тест
- C) Автоматжуулсан тест
- D) Кодын хамралт шалгах
Зөв хариулт: B
Тайлбар: UAT = User Acceptance Testing. Захиалагч эсвэл эцсийн хэрэглэгч бодит орчинд системийг шалгаж, шаардлага хангасан эсэхийг баталгаажуулна.
Тест 93
JUnit 5-д @AfterAll аннотаци юу хийдэг вэ?
- A) Тест бүрийн дараа ажиллах
- B) Бүх тестийн ДАРАА 1 удаа ажиллах (cleanup)
- C) Тестийн өмнө ажиллах
- D) Тестийг давтах
Зөв хариулт: B
Тайлбар:
@AfterAllнь бүх тестийн ДАРАА НЭГ удаа ажиллана (static method). DB холболт хаах, нөөц чөлөөлөх зэрэгт ашиглана.
Тест 94
assertFalse(condition) юу хийдэг вэ?
- A) condition TRUE эсэхийг шалгах
- B) condition FALSE эсэхийг шалгах
- C) condition null эсэхийг шалгах
- D) Exception шалгах
Зөв хариулт: B
Тайлбар:
assertFalse(condition)нь condition FALSE байгаа эсэхийг шалгана. FALSE бол pass, TRUE бол fail.assertTrue-ийн эсрэг.
Тест 95
Test-Driven Development-ийн давуу талуудаас аль нь БИШ вэ?
- A) Алдааг эрт олдог
- B) Кодын чанар сайжирдаг
- C) Хөгжүүлэлт үргэлж ХУРДАН болдог
- D) Баримтжуулалт болдог
Зөв хариулт: C
Тайлбар: TDD нь эхэндээ УДААН — тест бичихэд нэмэлт хугацаа шаардагддаг. Гэхдээ урт хугацаанд алдааны тоог багасгаж, чанарыг сайжруулдаг.
Тест 96
Дараах кодонд буруу юу байна?
@Test void testMultiple() {
assertEquals(5, calc.add(2, 3));
assertEquals(6, calc.multiply(2, 3));
assertNotNull(calc.toString());
}
- A) Код зөв
- B) Нэг тестэд олон зүйл шалгаж байна — "нэг тест, нэг зүйл" зарчим зөрчиж байна
- C) assertEquals алдаатай
- D) calc объект байхгүй
Зөв хариулт: B
Тайлбар: Нэг тестэд add(), multiply(), toString() гэсэн 3 өөр зүйл шалгаж байна. Тест fail болоход яг аль нь буруу болсон нь тодорхой бус. Тус тусдаа бичих ёстой.
Тест 97
Mockito дахь anyString() юу хийдэг вэ?
- A) Тодорхой нэг String утгыг шалгах
- B) АЛИВАА String утгыг хүлээн авах (argument matcher)
- C) String үүсгэх
- D) Тестийг давтах
Зөв хариулт: B
Тайлбар:
anyString()нь argument matcher — ямар ч String утга дамжуулахад ажиллана.when(mock.method(anyString())).thenReturn(...)— Ямар ч String-д ижил хариу буцаана.
Тест 98
Тестчилэлийн "V-Model" гэж юу вэ?
- A) Зөвхөн unit тест
- B) Хөгжүүлэлтийн шат бүрт тохирох тестийн түвшинг тодорхойлсон загвар
- C) Тестийн фреймворк
- D) Кодын бүтэц
Зөв хариулт: B
Тайлбар: V-Model: Зүүн тал = Хөгжүүлэлт (Шаардлага → Дизайн → Код). Баруун тал = Тест (Unit → Integration → System → Acceptance). Шат бүрт тохирох тест.
Тест 99
Дараах аль нь тестчилэлийн зорилго БИШ вэ?
- A) Алдаа олох
- B) Чанар баталгаажуулах
- C) Бүх алдааг 100% олох
- D) Итгэлцэл бий болгох
Зөв хариулт: C
Тайлбар: Бүх алдааг 100% олох БОЛОМЖГҮЙ (ISTQB зарчим 1, 2). Тестчилэл нь алдааг ОЛОХ, чанарыг баталгаажуулах, итгэлцэл бий болгоход зориулагдсан.
Тест 100
Тестчилэл яагаад програм хангамжийн бүтээлтэд чухал вэ?
- A) Зөвхөн компаниуд шаарддаг
- B) Алдааг эрт олж засах зардлыг бууруулж, кодын чанар, итгэлцэл, засвар хялбар байдлыг хангадаг
- C) Код хурдан ажиллуулдаг
- D) Компайлер шаарддаг
Зөв хариулт: B
Тайлбар: Тестчилэл нь алдааг ЭРТ олж засах зардлыг бууруулдаг (100× хэмнэлт), кодын ЧАНАР-ыг сайжруулдаг, шинэ код нэмэхэд ИТГЭЛЦЭЛ өгдөг, regression алдаанаас ХАМГААЛДАГ. Мэргэжлийн хөгжүүлэгчийн чухал ур чадвар.
📚 Ашигласан эх сурвалжууд:
- ISTQB Foundation Level Syllabus (v4.0, 2023)
- JUnit 5 User Guide — junit.org/junit5
- Kent Beck — Test-Driven Development: By Example
- Software Engineering: A Modern Approach — Chapter 8: Testing
- Robert C. Martin — Clean Code, Chapter 9: Unit Tests
- Mockito Framework Documentation — site.mockito.org
- IEEE SWEBOK — Software Testing Knowledge Area
- Martin Fowler — Test Pyramid, Mocks Aren't Stubs