
Programmalıq injiniringge kirisiw / 12-ameliy PI_K
.pdf12-ámeliy sabaq. Test sınawların jazıw hám tekseriw. Úles programma hám sistemanı testlew.
Jumıstıń maqseti: Ámeliy sabaqtıń maqseti studentlerge programmalıq injiniringde test sınawların ámelge asırıw metodları, úles programmalardı hám sistemalardı testlew processleri menen tanısıw imkaniyatın beriw. Sabaq dawamında studentler test keyslerin jazıw, test sınawların jobalaw hám ámelge asırıw, sonıń ishinde modullik hám integraciyalıq testlewdi orınlaw boyınsha ámeliy tájiriybe aladı.
Ámeliy bólim
Programmalıq injiniringde sapalı ónim jaratıw ushın testlew processi ayrıqsha áhmiyetke iye. Testlew – programmalıq támiynattıń aldın ala belgilengen talaplarǵa muwapıq jumıs isleytuǵının anıqlawǵa baǵdarlanǵan process. Tómende úles programma hám sistemanı testlewdiń izbe-iz basqıshları keltirilgen.
1. Testlew túrleri menen tanısıw. Programmalıq támiynattı testlewdiń birneshe túrleri bar:
Modullik testlew (Unit Testing) – programmanıń ayırım bóleklerin (funkciya, klass) izolyaciyada tekseredi. Bul testlew túri programmanıń hár bir komponenti óz funkcionallıǵın durıs orınlaytuǵının tekseriw ushın qollanıladı.
Integraciyalıq testlew (Integration Testing) – bir-biri menen baylanısqan modullerdiń birgelikte jumıs islewin tekseredi. Bul process dawamında moduller arasındaǵı baylanıs hám maǵlıwmat almasıw processi tekseriledi.
Sistema testlewi (System Testing) – programmalıq támiynattı pútin sistema sıpatında tekseredi. Bunda barlıq komponentler birge jumıs isleytuǵını anıqlanadı.
Funkcionallıq testlew (Functional Testing) – programmalıq támiynattıń funkcionallıq talaplarǵa muwapıq jumıs isleytuǵının tekseredi.
Ónimlilik testlewi (Performance Testing) – programmalıq támiynattıń júkleme astında qalay isleytuǵının tekseredi.
2. JUnit penen modullik testlew. Java tilinde jazılǵan programmalardı testlew ushın JUnit freymvorki keń qollanıladı. Tómende JUnit penen modullik testlew mısalı keltirilgen:
Adım 1: Testlew ushın klass jazıw
Aldın ala biz esaplawlar islenetuǵın Calculator klasın jaratamız:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) { return a - b;
}
public int multiply(int a, int b) { return a * b;
}
public double divide(int a, int b) { if (b == 0) {
throw new IllegalArgumentException("Bóliwshi nolge teń bolmawı kerek");
}
return (double) a / b;
}
}
Adım 2: JUnit test klasın jaratıw
Endi Calculator klası ushın test klasın jaratamız:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class CalculatorTest {
private Calculator calculator;
@BeforeEach
public void setUp() {
calculator = new Calculator();
}
@Test
public void testAdd() {
assertEquals(5, calculator.add(2, 3), "2 + 3 = 5 bolıwı
kerek");
assertEquals(0, calculator.add(-1, 1), "-1 + 1 = 0 bolıwı kerek");
assertEquals(-10, calculator.add(-7, -3), "-7 + (-3) = - 10 bolıwı kerek");
}
@Test
public void testSubtract() {
assertEquals(-1, calculator.subtract(2, 3), "2 - 3 = -1 bolıwı kerek");
assertEquals(5, calculator.subtract(10, 5), "10 - 5 = 5 bolıwı kerek");
}
@Test
public void testMultiply() {
assertEquals(6, calculator.multiply(2, 3), "2 * 3 = 6 bolıwı kerek");
assertEquals(0, calculator.multiply(0, 5), "0 * 5 = 0 bolıwı kerek");
assertEquals(-10, calculator.multiply(2, -5), "2 * (-5) = -10 bolıwı kerek");
}
@Test
public void testDivide() {
assertEquals(2.0, calculator.divide(6, 3), "6 / 3 = 2.0 bolıwı kerek");
assertEquals(0.5, calculator.divide(1, 2), "1 / 2 = 0.5 bolıwı kerek");
}
@Test
public void testDivideByZero() { assertThrows(IllegalArgumentException.class, () ->
calculator.divide(5, 0),
"Nolge bóliw IllegalArgumentException keltirip shıǵarıwı kerek");
}
}
Adım 3: Testlerdi orınlaw
JUnit freymvorki menen testlerdi orınlaw ushın IDE qurallarınan paydalanamız
(IntelliJ IDEA, Eclipse) yamasa komanda qatarın qollanamız. Testler orınlanǵannan soń, nátiyjeler talqılanadı.
3. Integraciyalıq testlewdi ámelge asırıw. Integraciyalıq testlew ushın eki klasstıń óz-ara baylanısın tekseremiz.
Adım 1: Testlenetuǵın klasslar jaratıw
Mısal ushın, bank operaciyaların modellestiriwshi eki klass jaratamız:
// Account klası - bank esap dápterin uslaydı public class Account {
private int id;
private double balance;
public Account(int id, double initialBalance) { this.id = id;
this.balance = initialBalance;
}
public double getBalance() { return balance;
}
public void deposit(double amount) { if (amount <= 0) {
throw new IllegalArgumentException("Depozit summası oń san bolıwı kerek");
}
balance += amount;
}
public void withdraw(double amount) { if (amount <= 0) {
throw new IllegalArgumentException("Alıw summası oń san bolıwı kerek");
}
if (amount > balance) {
throw new IllegalArgumentException("Esap dápterde jetkilikli qarjı joq");
}
balance -= amount;
}
public int getId() { return id;
}
}
// TransferService klası - esap dápterler arasında tranzakciya júrgizedi
public class TransferService {
public void transferMoney(Account from, Account to, double amount) {
if (from == null || to == null) {
throw new IllegalArgumentException("Esap dápter nul bolmawı kerek");
}
if (amount <= 0) {
throw new IllegalArgumentException("Tranzakciya summası oń san bolıwı kerek");
}
from.withdraw(amount);
to.deposit(amount);
}
}
Adım 2: Integraciyalıq test jazıw
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class TransferServiceIntegrationTest {
private Account sourceAccount; private Account targetAccount;
private TransferService transferService;
@BeforeEach
public void setUp() {
sourceAccount = new Account(1, 1000.0); targetAccount = new Account(2, 500.0); transferService = new TransferService();
}
@Test
public void testSuccessfulTransfer() { // Tranzakciya summası
double transferAmount = 300.0;
// Tranzakciyadan aldın balanslardı saqlap alıw double initialSourceBalance =
sourceAccount.getBalance();
double initialTargetBalance = targetAccount.getBalance();
// Tranzakciyanı orınlaw transferService.transferMoney(sourceAccount,
targetAccount, transferAmount);
// Nátiyjelerdi tekseriw assertEquals(initialSourceBalance - transferAmount,
sourceAccount.getBalance(),
"Puldı jiberiwshi táreptiń balansı tómen ketiwi
kerek");
assertEquals(initialTargetBalance + transferAmount, targetAccount.getBalance(),
"Puldı alıwshı táreptiń balansı kóbeyiwi
kerek");
}
@Test
public void testInsufficientFunds() {
//Esap dápterde bar summadan úlken summa menen tranzakciya qılıw
double transferAmount = 1500.0;
//Nátiyje - qátelik payda bolıwı kerek assertThrows(IllegalArgumentException.class,
() ->
transferService.transferMoney(sourceAccount, targetAccount, transferAmount),
"Jetkiliksiz qarjı jaǵdayında qátelik payda
bolıwı kerek");
// Esap dápterler balansı ózgermey qalıwı kerek assertEquals(1000.0, sourceAccount.getBalance(), "Puldı
jiberiwshi táreptiń balansı ózgermewi kerek"); assertEquals(500.0, targetAccount.getBalance(), "Puldı
alıwshı táreptiń balansı ózgermewi kerek");
}
@Test
public void testNegativeTransferAmount() {
//Teris san menen tranzakciya qılıw double transferAmount = -100.0;
//Qátelik payda bolıwı kerek assertThrows(IllegalArgumentException.class,
() -> transferService.transferMoney(sourceAccount, targetAccount, transferAmount),
"Teris tranzakciya summası qátelik keltirip shıǵarıwı kerek");
}
}
4. Sistema testlewin ámelge asırıw
Sistema testlewinde programmalıq támiynat tolıq sistema retinde tekseriledi. Bul process ushın kóbinese Selenium, REST Assured sıyaqlı freymvorkler paydalanıladı. Tómende REST API ushın sistema testlewi keltirilgen:
import io.restassured.RestAssured; import io.restassured.http.ContentType; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*;
public class UserServiceSystemTest {
@BeforeAll
public static void setup() {
// REST API bazalıq adresin ornatıw RestAssured.baseURI = "http://localhost"; RestAssured.port = 8080;
}
@Test
public void testCreateUser() { String userJson = "{"
+"\"username\": \"testuser\","
+"\"email\": \"test@example.com\","
+"\"password\": \"securepassword123\""
+"}";
// POST sorawı arqalı jańa paydalanıwshı jaratıw given()
.contentType(ContentType.JSON)
.body(userJson)
.when()
.post("/api/users")
.then()
.statusCode(201)
.body("id", notNullValue())
.body("username", equalTo("testuser"))
.body("email", equalTo("test@example.com"));
}
@Test
public void testGetUserById() {
// GET sorawı arqalı paydalanıwshı maǵlıwmatların alıwdı
tekseriw
given()
.when()
.get("/api/users/1")
.then()
.statusCode(200)
.body("id", equalTo(1))
.body("username", notNullValue())
.body("email", notNullValue());
}
@Test
public void testUpdateUser() { String updateJson = "{"
+"\"email\": \"updated@example.com\""
+"}";
//PUT sorawı arqalı paydalanıwshı maǵlıwmatın jańalawdı
tekseriw
given()
.contentType(ContentType.JSON)
.body(updateJson)
.when()
.put("/api/users/1")
.then()
.statusCode(200)
.body("email", equalTo("updated@example.com"));
}
@Test
public void testDeleteUser() {
// DELETE sorawı arqalı paydalanıwshını óshiriwdi
tekseriw
given()
.when()
.delete("/api/users/1")
.then()
.statusCode(204);
// Paydalanıwshı óshirilgenligin tekseriw given()
.when()
.get("/api/users/1")
.then()
.statusCode(404);
}
}
5. Testlew jobasın dúziw
Úlken programmalıq támiynat proektlerinde testlew jobasın dúziw áhmiyetli bolıp tabıladı. Testlew jobası tómendegilerdi óz ishine alıwı kerek:
1.Testlew strategiyası – qanday túrdegi testler ótkeriletuǵını, testlew ushın qanday resurslar zárúr ekenligi anıqlanadı.
2.Test keysler – hár bir funkcionallıq ushın konkret test keysler dúziledi.
3.Testlew grafigi – testlew processiniń múddetleri hám keste belgilenedi.
4.Testlew nátiyjelerin tallaw – testlew nátiyjeleri dokumentlestiriledi hám tallaw ótkeriledi.
6.Test-Driven Development (TDD) metodologiyası
Test-Driven Development – programmalastırıw metodologiyası, bunda dáslep testler jazıladı, sońınan usı testlerdi ámelge asırıw ushın kod jazıladı. TDD ciklı tómendegishe boladı:
1.Red: Óte almaytuǵın testti jazıw
2.Green: Testti ótiw ushın miniamal kod jazıw
3.Refactor: Kodtı jaqsılaw, lekin testler ótiwin saqlap qalıw
Tómende TDD mısalı keltirilgen:
Adım 1: Óte almaytuǵın test jazıw
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class StringUtilsTest {
@Test
public void testReverse() {
StringUtils utils = new StringUtils(); assertEquals("cba", utils.reverse("abc"), "abc sóziniń
teskerisin alıw");
assertEquals("", utils.reverse(""), "Bos jol teskerisin
alıw");

assertEquals("a", utils.reverse("a"), "Bir simvoldıń teskerisin alıw");
}
}
Adım 2: Minimal kod jazıw
public class StringUtils {
public String reverse(String input) { if (input == null) {
return null;
}
StringBuilder reversed = new StringBuilder(); for (int i = input.length() - 1; i >= 0; i--) {
reversed.append(input.charAt(i));
}
return reversed.toString();
}
}
Adım 3: Kodtı jaqsılaw
public class StringUtils {
public String reverse(String input) { if (input == null) {
return null;
}
return new StringBuilder(input).reverse().toString();
}
}
Ámeliy tapsırmalar
Tapsırma 1: Modullik testlew
Óz variantıńızǵa sáykes tómendegi klassqa JUnit paydalanıp test klass jazıń:
public class StringCalculator {
public int add(String numbers) { if (numbers.isEmpty()) {
return 0;
}
String[] parts = numbers.split(","); int sum = 0;
for (String part : parts) {
sum += Integer.parseInt(part.trim());
}
return sum;
}
}
Testler tómendegi jaǵdaylardı tekseriwi kerek:
Bos qatar berilgen jaǵdaydı
Bir sanlı qatar berilgen jaǵdaydı
Eki sanlı qatar berilgen jaǵdaydı
Kóp sanlı qatar berilgen jaǵdaydı
Teris san berilgen jaǵdaydı (bunda qátelik payda bolıwı kerek)
Tapsırma 2: Integraciyalıq testlew
Tómendegi klasslar arasındaǵı integraciyanı testleytuǵın test klass jazıń:
public class Product { private int id; private String name; private double price;
public Product(int id, String name, double price) { this.id = id;
this.name = name; this.price = price;
}
// Getter hám setter metodlar public int getId() { return id; }
public String getName() { return name; } public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
}
public class ShoppingCart {
private List<Product> items = new ArrayList<>();
public void addProduct(Product product) { items.add(product);
}
public void removeProduct(int productId) { items.removeIf(p -> p.getId() == productId);
}
public double calculateTotal() { return
items.stream().mapToDouble(Product::getPrice).sum();
}