Apidog

منصة تطوير API تعاونية متكاملة

تصميم API

توثيق API

تصحيح أخطاء API

محاكاة API

اختبار API الآلي

كيفية استخدام Selenium WebDriver لاختبار واجهات برمجة التطبيقات

@apidog

@apidog

Updated on أبريل 1, 2025

💡
قبل الغوص في درس سيلينيوم، تحقق من Apidog—أداة مجانية مصممة لتبسيط اختبار واجهات البرمجة للتطبيقات (API) والتكامل. مع واجهة Apidog البديهية، يمكنك بسهولة تصحيح وتحسين تدفقات عمل واجهات البرمجة الخاصة بك، مما يسهل عملية التطوير ويوفر لك وقتاً ثميناً. سواء كنت تبني واجهات برمجة التطبيقات أو تحل المشكلات، فإن Apidog يحتوي على كل ما تحتاجه لتعزيز سير عملك.
زر

عندما نفكر في سيلينيوم وبيئة التشغيل الخاصة به، نربط عادةً بينه وبين أتمتة المتصفح واختبار واجهة المستخدم. ومع ذلك، يمكن أن تكون سيلينيوم أداة قوية لاختبار واجهات البرمجة للتطبيقات (API) عند استخدامها بشكل صحيح. ستوجهك هذه الدورة خلال عملية الاستفادة من قدرات سيلينيوم وبيئة التشغيل الخاصة به لإجراء اختبار واجهات البرمجة للتطبيقات، مع تو提供 أمثلة عملية وأفضل الممارسات.

يشمل اختبار واجهات البرمجة (API) اختبار واجهات البرمجة الخاصة بالتطبيق مباشرة، والتحقق من وظيفتها وموثوقيتها وأدائها وأمانها. بينما توجد أدوات مخصصة لاختبار واجهات البرمجة مثل Postman وREST Assured أو SoapUI، يمكن أن تكون سيلينيوم وبيئة التشغيل الخاصة بها إضافة قيمة لمجموعة أدوات اختبار واجهات البرمجة الخاصة بك، خاصة عندما تريد دمج اختبار واجهة المستخدم واختبار واجهات البرمجة في نفس الإطار.

المتطلبات الأساسية

قبل الغوص في اختبار واجهات البرمجة باستخدام سيلينيوم وبيئة التشغيل الخاصة بها، تأكد من أنك تمتلك:

  1. معرفة أساسية بسيلينيوم وبيئة التشغيل الخاصة بها
  2. لغة برمجة من اختيارك (Java، Python، C#، JavaScript)
  3. إعداد سيلينيوم وبيئة التشغيل الخاصة بها في بيئة التطوير الخاصة بك
  4. فهم واجهات البرمجة REST/SOAP
  5. معرفة أساسية بأساليب HTTP (GET، POST، PUT، DELETE)

فهم البنية

تجعل بنية سيلينيوم وبيئة التشغيل الخاصة بها مناسبة لاختبار واجهات البرمجة من خلال قدرتها على:

  1. إرسال طلبات HTTP مباشرة باستخدام المكتبات المدمجة أو الخارجية
  2. التعامل مع الاستجابات والتحقق من البيانات
  3. التكامل مع أطر الاختبار الموجودة
  4. إدارة بيانات الاختبار والبيئات

إعداد بيئتك

لنقم بإعداد بيئة أساسية لاختبار واجهات البرمجة باستخدام سيلينيوم وبيئة التشغيل الخاصة بها:

مثال على Java

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class SeleniumApiTesting {
    private WebDriver driver;

    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless"); // وضع غير مرئي لاختبار واجهات البرمجة
        driver = new ChromeDriver(options);
    }

    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

مثال على Python

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests
import json

def setup_driver():
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # وضع غير مرئي لاختبار واجهات البرمجة
    driver = webdriver.Chrome(options=chrome_options)
    return driver

def teardown_driver(driver):
    if driver is not None:
        driver.quit()

أساليب اختبار واجهات البرمجة باستخدام سيلينيوم وبيئة التشغيل الخاصة بها

1. استخدام المكتبات الأصلية لـ HTTP

النهج الأكثر مباشرة هو استخدام المكتبات الأصلية لـ HTTP بلغة البرمجة الخاصة بك مع سيلينيوم وبيئة التشغيل الخاصة بها.

مثال على Java - طلب GET

public String performGetRequest(String endpoint) throws IOException {
    URL url = new URL(endpoint);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");

    int responseCode = connection.getResponseCode();
    System.out.println("رمز استجابة GET: " + responseCode);

    if (responseCode == HttpURLConnection.HTTP_OK) {
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        return response.toString();
    } else {
        return "فشل طلب GET مع رمز الاستجابة: " + responseCode;
    }
}

مثال على Python - طلب POST

def perform_post_request(endpoint, payload):
    headers = {'Content-Type': 'application/json'}
    response = requests.post(endpoint, data=json.dumps(payload), headers=headers)

    print(f"رمز استجابة POST: {response.status_code}")

    if response.status_code == 200:
        return response.json()
    else:
        return f"فشل طلب POST مع رمز الاستجابة: {response.status_code}"

2. استخدام JavaScriptExecutor لاستدعاءات AJAX

طريقة أخرى هي استخدام JavaScriptExecutor الخاص بسيلينيوم لإجراء استدعاءات AJAX مباشرة من المتصفح.

مثال على Java

import org.openqa.selenium.JavascriptExecutor;

public String performApiCallWithJsExecutor(String endpoint, String method, String payload) {
    String script = String.format(
        "var xhr = new XMLHttpRequest();" +
        "xhr.open('%s', '%s', false);" +
        "xhr.setRequestHeader('Content-Type', 'application/json');" +
        "xhr.send('%s');" +
        "return xhr.responseText;",
        method, endpoint, payload
    );

    return (String) ((JavascriptExecutor) driver).executeScript(script);
}

مثال على Python

def perform_api_call_with_js_executor(driver, endpoint, method, payload):
    script = f"""
        var xhr = new XMLHttpRequest();
        xhr.open('{method}', '{endpoint}', false);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send('{payload}');
        return xhr.responseText;
    """

    return driver.execute_script(script)

3. اعتراض وتعديل استدعاءات واجهة البرمجة للتطبيقات

يمكن استخدام سيلينيوم وبيئة التشغيل الخاصة بها لاعتراض وتعديل استدعاءات واجهة البرمجة التي يقوم بها التطبيق، خاصة عند دمجها مع أدوات وكيل مثل BrowserMob Proxy.

مثال على Java مع BrowserMob Proxy

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import org.openqa.selenium.Proxy;

public void setupProxyForApiInterception() {
    // بدء الوكيل
    BrowserMobProxy proxy = new BrowserMobProxyServer();
    proxy.start(0);

    // الحصول على كائن وكيل سيلينيوم
    Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

    // تكوين Chrome لاستخدام الوكيل
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", seleniumProxy);

    // إنشاء كائن WebDriver
    driver = new ChromeDriver(options);

    // إضافة فلتر طلب لاعتراض استدعاءات واجهة البرمجة
    proxy.addRequestFilter((request, contents, messageInfo) -> {
        if (request.getUri().contains("/api/")) {
            System.out.println("استدعاء واجهة البرمجة المعترض: " + request.getUri());
            // تعديل الرؤوس أو المعلمات أو جسم الطلب إذا لزم الأمر
        }
        return null;
    });

    // إضافة فلتر استجابة لفحص وتعديل استجابات واجهة البرمجة
    proxy.addResponseFilter((response, contents, messageInfo) -> {
        if (messageInfo.getOriginalRequest().getUri().contains("/api/")) {
            String responseBody = contents.getTextContents();
            System.out.println("استجابة واجهة البرمجة: " + responseBody);
            // تعديل الاستجابة إذا لزم الأمر
        }
    });
}

بناء إطار اختبار واجهة برمجة التطبيقات كامل

لنقم بإنشاء إطار اختبار واجهة برمجة تطبيقات أكثر تنظيمًا باستخدام سيلينيوم وبيئة التشغيل الخاصة بها:

مثال على Java

import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.IOException;

public class ApiTestFramework {
    private WebDriver driver;
    private final String BASE_URL = "<https://api.example.com>";

    @BeforeClass
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless");
        driver = new ChromeDriver(options);
    }

    @Test
    public void testGetUserEndpoint() throws IOException {
        String endpoint = BASE_URL + "/api/users/1";
        String response = performGetRequest(endpoint);

        JSONObject jsonResponse = new JSONObject(response);

        Assert.assertEquals(jsonResponse.getString("name"), "جون دو");
        Assert.assertEquals(jsonResponse.getInt("id"), 1);
        Assert.assertTrue(jsonResponse.has("البريد الإلكتروني"));
    }

    @Test
    public void testCreateUserEndpoint() throws IOException {
        String endpoint = BASE_URL + "/api/users";
        JSONObject payload = new JSONObject();
        payload.put("name", "جين سميث");
        payload.put("email", "jane.smith@example.com");

        String response = performPostRequest(endpoint, payload.toString());
        JSONObject jsonResponse = new JSONObject(response);

        Assert.assertTrue(jsonResponse.has("id"));
        Assert.assertEquals(jsonResponse.getString("name"), "جين سميث");
    }

    private String performGetRequest(String endpoint) throws IOException {
        // التنفيذ من المثال السابق
    }

    private String performPostRequest(String endpoint, String payload) throws IOException {
        URL url = new URL(endpoint);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // كتابة الحمولة إلى الاتصال
        try (java.io.OutputStream os = connection.getOutputStream()) {
            byte[] input = payload.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = connection.getResponseCode();
        System.out.println("رمز استجابة POST: " + responseCode);

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();
        }
    }

    @AfterClass
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

مثال على Python

import unittest
import json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests

class ApiTestFramework(unittest.TestCase):
    BASE_URL = "<https://api.example.com>"

    def setUp(self):
        chrome_options = Options()
        chrome_options.add_argument("--headless")
        self.driver = webdriver.Chrome(options=chrome_options)

    def test_get_user_endpoint(self):
        endpoint = self.BASE_URL + "/api/users/1"
        response = self.perform_get_request(endpoint)

        self.assertEqual(response['name'], "جون دو")
        self.assertEqual(response['id'], 1)
        self.assertIn('البريد الإلكتروني', response)

    def test_create_user_endpoint(self):
        endpoint = self.BASE_URL + "/api/users"
        payload = {
            "name": "جين سميث",
            "email": "jane.smith@example.com"
        }

        response = self.perform_post_request(endpoint, payload)

        self.assertIn('id', response)
        self.assertEqual(response['name'], "جين سميث")

    def perform_get_request(self, endpoint):
        response = requests.get(endpoint)
        return response.json() if response.status_code == 200 else None

    def perform_post_request(self, endpoint, payload):
        headers = {'Content-Type': 'application/json'}
        response = requests.post(endpoint, data=json.dumps(payload), headers=headers)
        return response.json() if response.status_code in [200, 201] else None

    def tearDown(self):
        if self.driver:
            self.driver.quit()

if __name__ == '__main__':
    unittest.main()

دمج اختبار واجهة المستخدم واختبار واجهة البرمجة للتطبيقات

إحدى أكبر مزايا استخدام سيلينيوم وبيئة التشغيل الخاصة بها لاختبار واجهة البرمجة للتطبيقات هي القدرة على دمج اختبارات واجهة المستخدم واختبارات واجهة البرمجة في نفس الإطار:

@Test
public void testLoginAndVerifyUserDataAPI() throws IOException {
    // جزء واجهة المستخدم: تسجيل الدخول عبر واجهة المستخدم
    driver.get("<https://example.com/login>");
    driver.findElement(By.id("username")).sendKeys("testuser");
    driver.findElement(By.id("password")).sendKeys("password");
    driver.findElement(By.id("loginButton")).click();

    // الانتظار حتى يكتمل تسجيل الدخول
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(ExpectedConditions.urlContains("/dashboard"));

    // استخراج رمز المصادقة من الكوكيز أو التخزين المحلي
    String authToken = (String) ((JavascriptExecutor) driver)
        .executeScript("return localStorage.getItem('authToken');");

    // جزء واجهة البرمجة: استخدام الرمز لإجراء استدعاء واجهة برمجة التطبيقات المحمية
    String endpoint = BASE_URL + "/api/user/profile";
    URL url = new URL(endpoint);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Authorization", "Bearer " + authToken);

    // معالجة والتحقق من استجابة واجهة البرمجة
    int responseCode = connection.getResponseCode();
    Assert.assertEquals(responseCode, 200);

    // قراءة وفحص الاستجابة
    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String response = in.lines().collect(Collectors.joining());
    in.close();

    JSONObject jsonResponse = new JSONObject(response);

    // التحقق من أن بيانات واجهة البرمجة تتطابق مع ما هو معروض في واجهة المستخدم
    String uiUsername = driver.findElement(By.id("profileUsername")).getText();
    Assert.assertEquals(jsonResponse.getString("username"), uiUsername);
}

أفضل الممارسات لاختبار واجهات البرمجة باستخدام سيلينيوم وبيئة التشغيل الخاصة بها

  1. استخدام وضع غير مرئي: عند إجراء اختبارات واجهة البرمجة البحتة، قم بتشغيل سيلينيوم في وضع غير مرئي لتوفير الموارد.
  2. فصل اختبارات واجهة البرمجة واختبارات واجهة المستخدم: بينما يمكنك دمجها، احتفظ باختبارات واجهة البرمجة واختبارات واجهة المستخدم مفصولة منطقياً.
  3. الاستفادة من مكتبات التأكيدات: استخدم مكتبات تأكيدات شاملة للتحقق من استجابات واجهة البرمجة.
  4. تنفيذ معالجة الأخطاء: أضف معالجة خطأ مناسبة لفشل واجهة البرمجة.
  5. تسجيل طلبات واستجابات واجهة البرمجة: لأغراض التصحيح، سجل جميع التفاعلات مع واجهات البرمجة.
  6. تخصيص الاختبارات: استخدم مزودي البيانات أو الاختبارات المخصصة لاختبار سيناريوهات مختلفة.
  7. تنفيذ معالجة المصادقة: أنشئ طرقاً قابلة لإعادة الاستخدام للتعامل مع المصادقة.
  8. النظر في الأداء: كن واعياً أن سيلينيوم قد تضيف أعباء مقارنة بأدوات اختبار واجهة البرمجة المخصصة.

قيود استخدام سيلينيوم وبيئة التشغيل الخاصة بها لاختبار واجهة البرمجة

  1. الأعباء المتعلقة بالأداء: سيلينيوم مصممة أساسًا لأتمتة المتصفح، وبالتالي تضيف أعباء للاختبار البحت لواجهات البرمجة.
  2. المميزات المحدودة لتخصص واجهة البرمجة: تقدم أدوات اختبار واجهة البرمجة المخصصة ميزات أكثر تحديداً لاختبار واجهات البرمجة.
  3. اعتماد المتصفح: حتى في الوضع غير المرئي، تتطلب سيلينيوم متصفحاً، وهو ما قد يكون غير ضروري لاختبار واجهة البرمجة.
  4. التعقيد: قد يكون إعداد سيلينيوم لاختبار واجهات البرمجة أكثر تعقيداً من استخدام أدوات اختبار واجهة البرمجة المخصصة.

متى تستخدم سيلينيوم وبيئة التشغيل الخاصة بها لاختبار واجهة البرمجة

سلينيوم وبيئة التشغيل الخاصة بها مناسبة للغاية لاختبار واجهة البرمجة في السيناريوهات التالية:

  1. عندما يكون لديك بالفعل إطار اختبار واجهة مستخدم قائم على سيلينيوم وتريد توسيعه.
  2. عندما تحتاج إلى اختبار سيناريوهات تشمل تفاعلات واجهة المستخدم وواجهة البرمجة.
  3. عندما تحتاج إلى اختبار واجهات البرمجة في سياق متصفح (مثل اختبار استدعاءات واجهة البرمجة الخاصة بـ JavaScript).
  4. عندما تريد اعتراض وتعديل استدعاءات واجهة البرمجة التي يقوم بها التطبيق.

الخلاصة

يمكن أن تكون سيلينيوم وبيئة التشغيل الخاصة بها أدوات متعددة الاستخدامات لاختبار واجهة البرمجة، خاصة عند التكامل مع أطر اختبار واجهة المستخدم الموجودة. بينما قد لا تحل محل أدوات اختبار واجهة البرمجة المخصصة للاحتياجات المعقدة، فإنها توفر وسيلة مرنة لدمج اختبار واجهة المستخدم واختبار واجهة البرمجة في إطار واحد.

من خلال الاستفادة من الأساليب والأمثلة المقدمة في هذه الدورة، يمكنك استخدام سيلينيوم وبيئة التشغيل الخاصة بها بشكل فعال لاحتياجات اختبار واجهة البرمجة الخاصة بك. تذكر أن تأخذ بعين الاعتبار المفاضلات واختر الأداة الصحيحة لاحتياجات اختبارك الخاصة.

سواء كنت تختبر واجهات برمجة REST أو خدمات SOAP أو نقاط نهاية GraphQL، يمكن أن تساعدك سيلينيوم وبيئة التشغيل الخاصة بها في إنشاء اختبارات شاملة تتحقق من كل من واجهة المستخدم الخاصة بتطبيقك ووظائف واجهة برمجيات APIs الأساسية له.

للاحتياجات الأكثر تقدماً في مجال اختبار واجهة البرمجة، قد ترغب في التفكير في دمج سيلينيوم وبيئة التشغيل الخاصة بها مع مكتبات أو إطارات اختبار واجهة البرمجة المخصصة مثل REST Assured (لـ Java) أو Requests (لـ Python) للحصول على أفضل ما في العالمين.

اختبار سعيد!