SSD Nodes Learn 🎉 VPS $5.50/மாதம் முதல்

VPS-ல் API mocking மற்றும் testing செய்வது எப்படி?

Self-hosted API mocking மற்றும் testing முறைகளை உங்கள் சொந்த VPS-ல் அமைப்பது எப்படி என்பதை அறிக. WireMock மற்றும் Hurl கருவிகளைப் பயன்படுத்தி CI சூழலில் API சோதனைகளை எளிதாக்குங்கள்.

ஒரே repository-ஐப் பகிரும் இரண்டு பணிகள்

Self-hosted API mocking மற்றும் testing ஆகிய இரண்டும் வெவ்வேறு பணிகள். இவற்றை ஒன்றாகக் கருதுவது ஒரு வார காலத்தை வீணடிக்கும். CI-லிருந்து உங்களால் அழைக்க முடியாத ஒரு dependency-க்கு மாற்றாக mock server செயல்படுகிறது: ஒரு payment provider, ஒரு partner API, rate limit செய்யப்பட்ட upstream, அல்லது மற்றொரு குழு இன்னும் வெளியிடாத (ship செய்யாத) ஒரு service. ஒரு API test runner உங்கள் சொந்த endpoints-ஐ ஒரு குறிப்பிட்ட வரிசையில் அழைத்து, பதில்களைச் சரிபார்க்கும் (assert); ஒரு பதிலிலிருந்து மதிப்புகளை எடுத்து அடுத்த கோரிக்கையில் பயன்படுத்தும்.

இவை இரண்டுக்கும் எந்தத் தொடர்பும் இல்லை. ஒரு mock server எப்போதுமே pass அல்லது fail என்று அறிக்கை தராது. ஒரு card நிராகரிக்கப்படும்போது payment provider என்ன பதிலளிக்கும் என்பதில் test runner-க்கு எந்தக் கருத்தும் இல்லை. ஏற்கனவே ஒரு server-ஐ வாடகைக்கு எடுத்துள்ள பெரும்பாலான குழுக்கள், ஒரே Docker Compose கோப்பின் மூலம் இரண்டையும் தொடங்கி, ஒரே pull request-ல் அவற்றை ஆய்வு செய்கின்றன.

API mocking மற்றும் testing-ஐ ஏன் self-host செய்ய வேண்டும்?

உங்கள் fixtures-ல் உள்ள தரவுகள் production-ல் உள்ள தரவுகளைப் போலவே இருக்கும். API test-ல் உள்ள request body என்பது உண்மையான வாடிக்கையாளர் தரவு; இதில் பெயர் மாற்றப்பட்டிருக்கலாம், அல்லது யாரும் சரிபார்க்காததால் பெயர் மாற்றப்படாமலும் இருக்கலாம். பதிவு செய்யப்பட்ட stubs (recorded stubs) இன்னும் ஆபத்தானவை: proxy recording என்பது upstream என்ன பதிலளித்ததோ அதை அப்படியே சேமிக்கும். எனவே, recording மூலம் உருவாக்கப்பட்ட stub directory-ல் live tokens மற்றும் வாடிக்கையாளர்களின் மின்னஞ்சல் முகவரிகள் இருக்கும்; ஒவ்வொரு கோப்பையும் ஒருவர் சரிபார்க்கும் வரை அவை அங்கேயே இருக்கும். ஒரு hosted service-ல் இந்தத் தரவுகள் கசிந்தால், அது மற்றவர்களுக்குப் பாதிப்பை ஏற்படுத்தி, உங்கள் நிறுவனத்தின் பாதுகாப்பு மீறலாக (disclosure) மாறும்.

இரண்டாவது காரணம் அணுகல்தன்மை (reachability). ஒரு private address-ல் இயங்கும் service-ஐ hosted runner மூலம் அணுக முடியாது, எனவே அந்தத் test-ஐ இயக்கவே முடியாது. ஒவ்வொரு மாற்று வழியும் ஒரு செலவை அல்லது சிக்கலை உள்ளடக்கியது. test செய்வதற்காக API-ஐ இணையத்தில் வெளியிடுவது, அந்த service-ஐ private-ஆக வைத்திருந்ததற்கான நோக்கத்தையே சிதைத்துவிடும். ஒரு tunnel அல்லது public staging copy-ஐ பராமரிப்பது கூடுதல் வேலை; மேலும், releases-க்கு இடையில் staging copy-யானது production-லிருந்து மாறுபட்டு (drift) போக வாய்ப்புள்ளது. அதே private network-ல் உள்ள ஒரு runner, service-ஐ நேரடியாக அழைக்கும். இதற்கு எந்த கூடுதல் அமைப்பும் தேவையில்லை. இதுவே a self-hosted GitHub Actions runner-ஐப் பயன்படுத்துவதற்கான நடைமுறை சார்ந்த காரணமாகும்.

எந்த self-hosted mock server-ஐ நீங்கள் இயக்க வேண்டும்?

இவை ஒவ்வொன்றும் உங்களுக்குச் சொந்தமான ஒரு server-ல் container-ஆக இயங்குகின்றன. இதில் எது உண்மையான ஆதாரமாக (source of truth) செயல்படுகிறது என்பதே முக்கியமான கேள்வி; ஏனெனில், container-ஐ மீண்டும் உருவாக்கும்போது அது உங்களுக்குச் சுலபமாக முடியுமா அல்லது ஒரு மதியப் பொழுதை வீணாக்குமா என்பதை இதுவே தீர்மானிக்கிறது.

  • WireMock: ஒவ்வொரு stub-ஐயும் mappings/ கோப்பகத்தில் ஒரு JSON கோப்பாகச் சேமிக்கிறது, பெரிய response bodies __files/-ல் இருக்கும். இதன் image wiremock/wiremock, container-க்குள் இதன் root கோப்பகம் /home/wiremock, மேலும் இது ஒரு recording proxy-ஆகவும் செயல்படுகிறது. கோப்புகள் வட்டில் (disk) இருப்பதால், மற்ற code-களைப் போலவே இந்த mock-களையும் git-ல் பராமரிக்கலாம்.
  • Mockoon CLI: முழு mock API-யையும் ஒரே JSON தரவுக் கோப்பில் வைத்திருக்கிறது. இதை npm install -g @mockoon/cli மூலம் நிறுவி, mockoon-cli start --data ./data-file.json மூலம் தொடங்கலாம், அல்லது அந்த கோப்பை bind mount செய்து mockoon/cli image-ஐ இயக்கலாம். இதன் desktop app அதே கோப்பைத்தான் திருத்துகிறது, எனவே UI-ல் வடிவமைப்பதும் அதன் முடிவுகளை commit செய்வதும் இணக்கமாக இருக்கும்.
  • MockServer: இது mockserver/mockserver image-லிருந்து இயங்குகிறது மற்றும் 1080 port-ல் கேட்கிறது (listens). இதற்கான எதிர்பார்ப்புகள் (expectations) அதன் சொந்த REST API வழியாக வருகின்றன; இது test code-க்கு வசதியானது, ஆனால் deployment-க்கு ஆபத்தானது: ஒரு HTTP அழைப்பின் மூலம் உருவாக்கப்பட்ட எதிர்பார்ப்பு, container restart ஆகும்போது அழிந்துவிடும். நிரந்தரமாக இருக்க வேண்டிய stubs-க்கு அதன் JSON initialization கோப்பைப் பயன்படுத்தவும்.
  • Prism: இது தனித்தனி stub கோப்புகளுக்குப் பதிலாக, உங்கள் OpenAPI ஆவணத்திலிருந்து mock-ஐ உருவாக்குகிறது. இதை npm install -g @stoplight/prism-cli மூலம் நிறுவி, பின் prism mock openapi.yaml-ஐ இயக்கவும். container-க்குள் -h 0.0.0.0-ஐச் சேர்க்கவும், ஏனெனில் Prism இயல்பாகவே localhost-ல் பிணைக்கப்படுவதால், container-க்கு வெளியிலிருந்து அதை அணுக முடியாது.
  • Microcks: இது ஒரு பெரிய விருப்பம்: OpenAPI ஆவணங்கள் மற்றும் Postman collections-ஐ இறக்குமதி செய்து, அவற்றை mock-களாக வழங்கி, contract tests-ஐ இயக்கும் ஒரு web UI இது. முழுமையான நிறுவலுக்கு MongoDB மற்றும் Keycloak, அத்துடன் அதன் async வசதிகளுக்கு Kafka தேவை. அனைத்தையும் உள்ளடக்கிய microcks-uber image-ல் in-memory MongoDB உள்ளது; இது தற்காலிகப் பயன்பாட்டிற்கு மட்டுமே ஏற்றது என்று அந்தத் திட்டம் குறிப்பிடுகிறது. எனவே, அந்த UI-ல் உருவாக்கப்படும் எதையும் தற்காலிகமானதாகக் கருதி, மூல ஆவணங்களை (source artifacts) git-ல் பாதுகாக்கவும்.

எந்த self-hosted API test runner-ஐ நீங்கள் பயன்படுத்த வேண்டும்?

இங்கு செய்ய வேண்டிய பணி ஒரு வரிசைமுறை: அங்கீகரித்தல் (authenticate), ஒரு order-ஐ உருவாக்குதல், அதை மீண்டும் வாசித்தல், மற்றும் நிலை (state) மாறியுள்ளதா என்பதை உறுதிப்படுத்துதல். இதற்கு ஒரு response-லிருந்து பெறப்பட்ட மதிப்பை அடுத்த request-ல் பயன்படுத்த வேண்டும். அழைப்புகளுக்கு இடையே state-ஐ பராமரிக்க முடியாத ஒரு கருவி, API test அல்ல, அது ஒரு health check மட்டுமே.

  • Hurl என்பது ஒரே binary மூலம் plain text கோப்புகளில் உள்ள HTTP request-களை இயக்கும். ஒரு [Captures] பகுதி response-லிருந்து மதிப்புகளை எடுக்கும், ஒரு [Asserts] பகுதி அவற்றைச் சரிபார்க்கும், மேலும் --test அதை ஒரு test runner-ஆக மாற்றி சுருக்கத்தையும் exit code-ஐயும் வழங்கும். ஆகஸ்ட் 2026 நிலவரப்படி, 8.0.1 பதிப்பு தற்போதைய பதிப்பாகும்.
  • Bruno CLI என்பது .bru கோப்புகளைக் கொண்ட ஒரு கோப்புறையை இயக்கும். npm install -g @usebruno/cli மூலம் நிறுவி, பின் bru run folder --env Local --reporter-junit results.xml மூலம் இயக்கவும். இதன் collection வடிவம் கோப்பகத்தில் உள்ள text கோப்புகளாகவே இருப்பதால், மாற்றங்களை (diffs) review செய்யும்போது எளிதாக வாசிக்க முடியும்.
  • Newman என்பது Postman collections-ஐ Postman-க்கு வெளியே இயக்கும்: npm install -g newman, பின் newman run collection.json -r cli,junit --reporter-junit-export results.xml. இதில் உள்ள சிக்கல் அதன் வடிவம் தான். collection என்பது ஏற்றுமதி செய்யப்பட்ட ஒரே JSON blob என்பதால், திருத்தங்கள் Postman-ல் மட்டுமே செய்ய முடியும்; git-ல் உள்ள கோப்பு காலாவதியான நகலாகவே இருக்கும்.
  • Schemathesis என்பது ஒரு மாறுபட்ட சோதனை முறை. இது OpenAPI schema-வை வாசித்து, உங்கள் schema-வின்படி சாத்தியமற்றது எனக் கருதப்படும் response-களை உருவாக்க முயற்சிக்கும்: uvx schemathesis run https://your.api/openapi.json. இது மென்பொருள் செயலிழப்புகளையும் (crashes) ஒப்பந்த மீறல்களையும் கண்டறியும். இது உங்கள் வணிக விதிகளைப் பற்றி அறியாது என்பதால், இது scripted suite-க்கு மாற்றாக இல்லாமல், அதற்கு இணையாகவே செயல்படும்.
  • Hoppscotch self-hosted என்பது web UI விருப்பமாகும், இதற்கு Postgres instance தேவை. இதை நிறுவும் முன் இந்த வர்த்தகத்தை (tradeoff) புரிந்துகொள்ளுங்கள்: collections உங்கள் repository-ல் இல்லாமல், database-ல் சேமிக்கப்படும்.

தவிர்க்க வேண்டிய ஒன்று. Step CI இன்னும் பல கருவிப் பட்டியல்களில் இடம்பெறுகிறது மற்றும் அதன் YAML workflow வடிவம் வாசிக்க எளிதாக உள்ளது, ஆனால் அதன் repository-ல் கடைசியாக ஆகஸ்ட் 2024-ல் தான் commit செய்யப்பட்டது. உங்கள் CI-க்கும் API-க்கும் இடையில் இருக்கும் ஒரு நிரல், பராமரிக்கப்படாத குறியீட்டிற்கு ஏற்ற இடமல்ல.

Mock server-ஐ firewall-க்கு பின்னால் வைத்தல்

கீழே உள்ள அமைப்பு, ஒரு payment provider-க்கு மாற்றாக WireMock-ஐ இயக்குகிறது. Compose file வடிவம் உங்களுக்குப் புதியது என்றால், Docker Compose on a VPS பகுதியில் இந்த பிரிவில் பயன்படுத்தப்படும் lifecycle கட்டளைகள் விளக்கப்பட்டுள்ளன.

services:
  mock-payments:
    image: wiremock/wiremock:3.13.2
    command: ["--verbose"]
    volumes:
      - ./mocks/payments:/home/wiremock
    ports:
      - "127.0.0.1:8080:8080"
    restart: unless-stopped

Port-க்கு முன்னால் உள்ள 127.0.0.1: prefix மிக முக்கியமானது. வெறும் 8080:8080 என்று குறிப்பிட்டால், அது உங்கள் public IP உட்பட அனைத்து interface-களிலும் mock-ஐ வெளியிடும். அப்போது ufw அந்த port-ஐத் தடுத்தாலும், Docker தனது சொந்த விதிகளை DOCKER iptables chain-ல் எழுதிவிடுவதால், அது தொடர்ந்து அணுகக்கூடியதாகவே இருக்கும். இந்த விதிகள் ufw-ன் INPUT விதிகளுக்கு முன்பே செயல்படுத்தப்படுகின்றன. அதற்குப் பதிலாக loopback address அல்லது private interface address-ல் bind செய்யவும்; அப்போதுதான் kernel வெளியிலிருந்து வரும் இணைப்புகளை ஏற்காது.

சோதனை செய்யப்படும் உங்கள் service, இந்த mock-ஐச் சுட்டிக்காட்ட வேண்டும். ஒரே compose project-ல் service இயங்கும்போது, compose தனது சொந்த network-ல் service பெயர்களை resolve செய்வதால், mock-ன் base URL http://mock-payments:8080 ஆக இருக்கும். service host-ல் இயங்கும்போது, அது http://127.0.0.1:8080 ஆக இருக்கும். இதை environment variable மூலம் அமைக்கவும்; குறியீட்டில் (code) ஒருபோதும் எழுத வேண்டாம், இல்லையெனில் test URL production-க்குச் சென்றுவிடும்.

Stubs-கள் ./mocks/payments/mappings/ கோப்பகத்தில் இருக்க வேண்டும், ஒவ்வொன்றும் தனித்தனி JSON கோப்பாக இருக்க வேண்டும்.

{
  "request": {
    "method": "POST",
    "urlPath": "/v1/charges",
    "bodyPatterns": [{ "matchesJsonPath": "$.amount" }]
  },
  "response": {
    "status": 201,
    "headers": { "Content-Type": "application/json" },
    "jsonBody": { "id": "ch_test_001", "status": "succeeded", "amount": 4200 }
  }
}

இதை இயக்கி, எவை ஏற்றப்பட்டுள்ளன என்பதைச் சரிபார்க்கவும்.

docker compose up -d --wait mock-payments
curl -fsS http://127.0.0.1:8080/__admin/mappings

--wait கட்டளையானது container ஆரோக்கியமாக இயங்கும் வரை காத்திருக்கும். WireMock image அதன் /__admin/health endpoint-க்கு எதிராக HEALTHCHECK-ஐக் கொண்டிருப்பதால் இது செயல்படுகிறது. mappings அழைப்பு, server வாசித்த அனைத்து stub-களையும் பட்டியலிடும். நீங்கள் எழுதிய stub அந்தப் பட்டியலில் இல்லை என்றால், அது ஏற்றப்படவில்லை என்று பொருள்: கோப்பு mappings/-க்குள் உள்ளதா அல்லது mounted root-ல் உள்ளதா என்பதைச் சரிபார்க்கவும், மேலும் JSON சரியாக உள்ளதா என்றும் பார்க்கவும்.

கோரிக்கை வரும்போது எந்த stub-உம் பொருந்தவில்லை என்றால், WireMock 404 பதிலைத் தரும். அதன் body Request was not matched என்று தொடங்கும், அதைத் தொடர்ந்து அது வைத்திருக்கும் மிக நெருக்கமான stub-உடன் உள்ள வேறுபாடு (diff) காட்டப்படும். எதையும் மாற்றுவதற்கு முன் அந்த diff-ஐப் படிக்கவும், ஏனெனில் அது வேறுபடும் துல்லியமான field-ஐக் குறிப்பிடும். பொதுவாக, stub-ல் /v1/charges என்று இருக்கும்போது, கோரிக்கையில் /v1/charge என்ற path இருக்கும்.

சோதனையை அழைப்புகளுக்கு இடையே நிலையைப் பராமரிக்கும் ஒரு தொடராக எழுதுதல்

Hurl கோப்புகள் plain text வடிவில் இருக்கும். திட்டத்தின் releases பக்கத்திலிருந்து deb கோப்பை நிறுவிக்கொள்ளவும்.

VERSION=8.0.1
curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/$VERSION/hurl_${VERSION}_amd64.deb
sudo apt update && sudo apt install ./hurl_${VERSION}_amd64.deb

உங்கள் API-ஐ mock-க்கு எதிராகச் சோதிக்கும் ஒரு தொகுப்பு tests/checkout.hurl-ல் உள்ளது.

POST {{base_url}}/orders
Content-Type: application/json
{
  "sku": "ssd-1tb",
  "amount": 4200
}
HTTP 201
[Captures]
order_id: jsonpath "$['id']"

GET {{base_url}}/orders/{{order_id}}
HTTP 200
[Asserts]
jsonpath "$.status" == "paid"
jsonpath "$.charge_id" == "ch_test_001"

[Captures] தொகுதிதான் இதை இரண்டு தொடர்பில்லாத கோரிக்கைகளாக இல்லாமல், ஒரு API சோதனையாக மாற்றுகிறது. order_id முதல் பதிலிலிருந்து படிக்கப்பட்டு, இரண்டாவது கோரிக்கையின் URL-ல் சேர்க்கப்படுகிறது (interpolate). charge_id-ல் உள்ள assertion தான் இந்த முழுச் சோதனையின் முக்கிய நோக்கமாகும்: உங்கள் சேவை payment provider-ஐ அழைத்து, திரும்ப வந்த தகவலைச் சேமித்ததை இது உறுதிப்படுத்துகிறது. மேலும், அது ஒப்பிடும் மதிப்பு நீங்கள் WireMock stub-ல் எழுதிய அதே மதிப்பாகும். இப்போது ஒரே கோப்பு இந்தச் செயல்பாட்டின் இரண்டு பகுதிகளையும் உள்ளடக்குகிறது.

hurl --test --variable base_url=http://127.0.0.1:3000 \
  --report-junit reports/junit.xml \
  --report-json reports/json \
  tests/

வெற்றிகரமான சோதனையின் போது, ஒவ்வொரு கோப்பிற்கும் ஒரு வரியும், இறுதியில் ஒரு சுருக்கமும் அச்சிடப்படும்.

tests/checkout.hurl: Success (2 request(s) in 61 ms)
Executed files:    1
Executed requests: 2 (30.1/s)
Succeeded files:   1 (100.0%)
Failed files:      0 (0.0%)
Duration:          64 ms

சோதனை தோல்வியுற்றால், error: Assert failure மூலம் கோப்பின் பெயர் மற்றும் வரி எண் காட்டப்படும். அதன்பின், பெறப்பட்ட மதிப்பும் எதிர்பார்க்கப்பட்ட மதிப்பும் ஒப்பிடப்படும். மேலும், hurl non-zero exit code-ஐத் தருவதால் CI செயல்முறை நின்றுவிடும். ஒருவேளை status-ல் நீங்கள் எதிர்பார்த்த paid-க்கு பதிலாக pending இருந்தால், உங்கள் சேவை mock-ன் பதிலைப் பரிசீலிக்கவில்லை என்று அர்த்தம். அடுத்து நீங்கள் செய்ய வேண்டியது /__admin/requests-ல் உள்ள WireMock request journal-ஐப் பார்ப்பதுதான்; அந்த அழைப்பு mock-ஐச் சென்றடைந்ததா என்பதை அது காட்டும்.

உங்கள் சொந்த CI runner-லிருந்து suite-ஐ இயக்குதல்

அதே server-ல் runner பதிவு செய்யப்பட்டிருந்தால், workflow சுருக்கமாக இருக்கும். Runner என்பது host-ல் இயங்கும் ஒரு சாதாரண process என்பதால், docker மற்றும் hurl ஆகியவற்றை அந்த host-ல் நிறுவியிருக்க வேண்டும். Hosted image-லிருந்து எந்த அமைப்பும் தானாக வராது.

name: api-tests
on: [push]
jobs:
  hurl:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - name: Start the mock
        run: docker compose up -d --wait mock-payments
      - name: Run the suite
        run: hurl --test --variable base_url=http://127.0.0.1:3000 --report-junit reports/junit.xml tests/
      - name: Archive the reports
        if: always()
        run: install -d /srv/api-tests/reports/$GITHUB_SHA && cp -r reports/. /srv/api-tests/reports/$GITHUB_SHA/
      - name: Stop the mock
        if: always()
        run: docker compose down

Archive step-ல் if: always() முக்கியமானது. அது இல்லையென்றால், test run தோல்வியடையும் போது copy செய்யப்படாது; இதனால் நீங்கள் பார்க்க வேண்டிய report-ஐ இழந்துவிடுவீர்கள். Runner அடுத்த job-க்கு முன் workspace-ஐ சுத்தம் செய்துவிடும், அதனுடன் report-களும் அழிந்துவிடும் என்பதால், அந்த copy-ஐ workspace-க்கு வெளியே சேமிக்க வேண்டும்.

முடிவுகளைத் தக்கவைத்தல், கடைசி ஓட்டத்தை மட்டும் பார்க்காமல் இருத்தல்

ஒவ்வொரு commit-க்கும் ஒரு JUnit XML கோப்பு ஒரு கேள்வியை மட்டுமே பதிலளிக்கும்: அது தேர்ச்சி பெற்றதா இல்லையா? ஒரு endpoint எப்போது மெதுவாகத் தொடங்கியது என்பதை இது கூறாது, ஏனெனில் நீங்கள் அந்த கோப்புகளைத் திறப்பதைத் நிறுத்திய பிறகு யாரும் அவற்றைப் படிப்பதில்லை. ஒரு போக்கைக் (trend) கண்டறிய, ஒவ்வொரு ஓட்டத்திற்கும் ஒரு வரிசையை அதே server-ல் உள்ள ஒரு சிறிய database-ல் சேர்க்கவும். commit SHA, கோப்பின் பெயர், தேர்ச்சி எண்ணிக்கை, தோல்வி எண்ணிக்கை மற்றும் கால அளவு ஆகியவற்றை உள்ளடக்கிய ஒரு ஒற்றை அட்டவணை போதுமானது. SQLite in production on a VPS இதற்கு ஒரு பொருத்தமான இடமாகும்: இது ஒரே கோப்பு, தனி server process தேவையில்லை, மேலும் நீங்கள் ஏற்கனவே எடுக்கும் backup-உடன் முழு வரலாறும் பாதுகாப்பாகச் சென்றுவிடும். JUnit XML-ஐ விட Hurl-ன் --report-json வெளியீட்டைப் பகுப்பாய்வு (parse) செய்யவும், ஏனெனில் இரண்டில் இதுவே கணினி வாசிக்கக்கூடிய வடிவமாகும்.

Container-ஐ மீண்டும் உருவாக்கும்போது எவை அழியாமல் இருக்க வேண்டும்

Mock வரையறைகளும் test suite-களும் source code-ன் ஒரு பகுதி. அவை எந்த service-ஐ விவரிக்கின்றனவோ, அதே repository-ல் இருக்க வேண்டும். ஒரு endpoint-ஐ மாற்றும் அதே pull request-லேயே இவையும் மாற்றப்பட வேண்டும். ஒரு web UI-ல் திருத்தப்படும் stub அல்லது runtime-ல் REST API வழியாக MockServer-க்கு அனுப்பப்படும் expectation, அந்த container-ன் memory-ல் அல்லது அந்த tool-ன் database-ல் மட்டுமே இருக்கும். docker compose down கட்டளையை இயக்கினால் அவை அழிந்துவிடும்; ஒரு test தவறான காரணத்திற்காக வெற்றி பெறும் வரை இது யாருக்கும் தெரியாது. உங்கள் repository-கள் உங்கள் சொந்த hardware-ல் இயங்கினால், self-hosted git server மூலம் fixtures மற்றும் service-ஐ ஒரே trust boundary-க்குள் வைத்திருக்க முடியும்.

அடுத்து நடைமுறை விதிகள். Image tag-களை pin செய்யவும், ஏனெனில் latest உங்கள் repository-ல் எந்த மாற்றமும் இல்லாமலேயே, mock கோரிக்கைகளை எவ்வாறு ஒப்பிடுகிறது என்பதை மாற்றக்கூடும். இந்தத் தோல்விக்கான காரணத்தைக் கண்டறிவது மிகவும் கடினம். Tool-க்கு எழுதும் அனுமதி தேவையில்லை என்றால், stub directory-களை read-only முறையில் mount செய்யவும். ஒரு mock-ன் stub-களை ஒருபோதும் named Docker volume-ல் வைக்க வேண்டாம்; ஏனெனில் அவ்வாறு செய்தால் அந்த volume உண்மையான ஆதாரமாக (source of truth) மாறிவிடும், git-ல் உள்ள நகல் கவனிக்கப்படாமல் தவறானதாகிவிடும்.

இன்னொன்று, இது பலரைச் சிக்கலில் தள்ளும். ஒரு proxy வழியாக உண்மையான traffic-ஐப் பதிவு செய்து stub-களை உருவாக்கினால், commit செய்வதற்கு முன்பு உருவாக்கப்பட்ட ஒவ்வொரு கோப்பையும் வாசிக்கவும். ஒரு பதிவு, upstream அனுப்பிய அனைத்தையும் அப்படியே வைத்திருக்கும்; இதில் bearer token-கள் மற்றும் வாடிக்கையாளரின் மின்னஞ்சல் முகவரிகளும் அடங்கும். அதை commit செய்வது உங்கள் repository-ல் நிரந்தரமாகச் சேர்த்துவிடும், ஏனெனில் git நீக்கப்பட்ட உள்ளடக்கத்தையும் வரலாற்றில் வைத்திருக்கும்.

FAQ

API mock server மற்றும் API test runner ஆகியவற்றுக்கு இடையே உள்ள வேறுபாடு என்ன?

Mock server என்பது கோரிக்கைகளுக்கு (requests) பதிலளிக்கும் ஒரு கருவி. CI சூழலில் உங்களால் அழைக்க முடியாத ஒரு dependency-க்கு மாற்றாக இது செயல்படுகிறது, இது ஒருபோதும் pass அல்லது fail என்று முடிவுகளைத் தெரிவிப்பதில்லை. ஒரு API test runner உங்கள் service-க்கு கோரிக்கைகளை அனுப்பி, பதில்களைச் சரிபார்த்து (assert), ஒரு அழைப்பின் மதிப்புகளை அடுத்த அழைப்பிற்குப் பயன்படுத்தி, ஏதேனும் assertion தோல்வியுற்றால் non-zero exit code-ஐ வழங்கும். இவை இரண்டும் வெவ்வேறு சிக்கல்களைத் தீர்க்கின்றன, பொதுவாக இவை இரண்டும் ஒரே நேரத்தில் பயன்படுத்தப்படும்: உங்கள் service mock-ஐ அழைக்கும்போது, test runner உங்கள் service-ஐ அழைக்கும்.

Hosted CI runner மூலம் ஒரு internal API-ஐ என்னால் சோதிக்க முடியுமா?

அதை வெளிப்படுத்தாமல் (expose) சோதிக்க முடியாது. Hosted runner உங்கள் network-க்கு வெளியே இருப்பதால், private address-ல் இயங்கும் service-ஐ அதனால் அணுக முடியாது. உங்களிடம் உள்ள தேர்வுகள்: API-ஐ public-ஆக வெளியிடுவது, tunnel-ஐ இயக்குவது அல்லது public staging நகலைப் பராமரிப்பது. இவை ஒவ்வொன்றும் தோல்வியடையக்கூடிய அல்லது தகவல்களை கசியவிடக்கூடிய ஒரு கூடுதல் அமைப்பை உருவாக்குகின்றன. அதே private network-ல் உள்ள ஒரு runner நேரடியாக service-ஐ அழைக்கும், இதுவே அணிகள் இந்த வேலையைத் தாங்களே (self-host) மேற்கொள்வதற்கான முக்கிய நடைமுறை காரணமாகும்.

Mock stubs மற்றும் API test suites எங்கே இருக்க வேண்டும்?

Git-ல், அவை விவரிக்கும் service-க்கு அருகிலேயே இருக்க வேண்டும். WireMock-ன் mappings/ directory, Mockoon-ன் data file, Hurl files மற்றும் Bruno-ன் .bru folder போன்ற கோப்புகளாக வரையறைகளைச் சேமிக்கும் கருவிகள், code review மற்றும் container rebuild-ஐ எளிதாக்குகின்றன. தரவுத்தளத்திலோ அல்லது web UI-லோ வரையறைகளைச் சேமிக்கும் கருவிகளுக்கு ஒரு backup திட்டம் மற்றும் export படிநிலை அவசியம்; container அழிந்த பிறகுதான் பலரும் இந்த export-ஐச் செய்ய மறந்துவிட்டதை உணர்கிறார்கள்.

Stub சரியாகத் தெரிந்தாலும், எனது mock ஏன் 404 பிழையைத் தருகிறது?

WireMock ஒரு stub-ஐ அது சரியாகப் பொருந்தினால் மட்டுமே வழங்கும். பொருந்தாத கோரிக்கைக்கு 404 பிழை கிடைக்கும், அதன் body Request was not matched என்று தொடங்கும். அதைத் தொடர்ந்து மிக நெருக்கமான stub-உடன் ஒப்பிடும் diff காட்டப்படும், அந்த diff எந்த field-ல் வேறுபாடு உள்ளது என்பதைக் குறிப்பிடும். பொதுவாக, path-ன் இறுதியில் உள்ள slash, stub கோரும் ஆனால் உங்கள் client அனுப்பாத Content-Type header, variable segment-க்கு stub urlPathPattern-ஐ எதிர்பார்க்கும்போது நீங்கள் பயன்படுத்திய urlPath, மற்றும் payload-உடன் பொருந்தாத body matcher ஆகியவை இதற்கு முக்கிய காரணங்களாகும். கோரிக்கை mock-ஐ அடைந்ததா என்பதை உறுதிப்படுத்த முதலில் /__admin/requests-ஐச் சரிபார்க்கவும்.

Staging environment இருந்தால் எனக்கு இன்னும் mock-கள் தேவையா?

ஆம், இரண்டு காரணங்களுக்காக. உங்கள் கட்டுப்பாட்டில் இல்லாத ஒரு upstream-ன் staging நகல் எப்போது வேண்டுமானாலும் செயலிழக்கலாம் அல்லது rate limit செய்யப்படலாம், இதனால் உங்கள் code-க்கும் இதற்கும் தொடர்பில்லாத காரணங்களால் உங்கள் suite தோல்வியடையலாம். மேலும், நிராகரிக்கப்பட்ட அட்டை (declined card) அல்லது gateway timeout போன்ற நீங்கள் சோதிக்க வேண்டிய முக்கியமான பதில்களை staging-ஆல் உருவாக்க முடியாது. ஒரு mock இவற்றைத் தேவைப்படும்போது local network வேகத்தில் வழங்கும், இது sandbox-ல் நிமிடக்கணக்கில் நடக்கும் சோதனையைச் சில நொடிகளில் முடிக்க உதவும். வெளியீட்டிற்கு முந்தைய இறுதிச் சரிபார்ப்பிற்கு staging-ஐ வைத்துக்கொண்டு, CI-ல் mock-களைப் பயன்படுத்தவும்.