diff --git a/src/components/CollapsibleCode.js b/src/components/CollapsibleCode.js new file mode 100644 index 000000000..544ddc006 --- /dev/null +++ b/src/components/CollapsibleCode.js @@ -0,0 +1,60 @@ +import React, {useState} from "react"; +import CodeBlock from "@theme/CodeBlock"; + +export default function CollapsibleCode({ + code, + language = "json", + previewLines = 10, +}) { + const [expanded, setExpanded] = useState(false); + const codeLines = code.trim().split("\n"); + const visibleCode = expanded + ? code.trim() + : codeLines.slice(0, previewLines).join("\n") + "\n# ..."; + + const handleCopy = () => { + try { + navigator.clipboard.writeText(code.trim()); + const btn = document.getElementById("copy-full-code"); + if (btn) { + const originalText = btn.innerText; + btn.innerText = "Copied!"; + setTimeout(() => (btn.innerText = originalText), 2000); + } + } catch (err) { + console.error("Failed to copy code:", err); + } + }; + + return ( +
+ {/* Pass the full code to CodeBlock so default copy button works */} + {visibleCode} + +
+ {codeLines.length > previewLines && ( + + )} + +
+
+ ); +} diff --git a/versioned_docs/version-3.0.0/ci-cd/github.md b/versioned_docs/version-3.0.0/ci-cd/github.md index 4a19473b9..0bd47a1ba 100644 --- a/versioned_docs/version-3.0.0/ci-cd/github.md +++ b/versioned_docs/version-3.0.0/ci-cd/github.md @@ -34,10 +34,6 @@ GitHub scripts are the easiest way to integrate Keploy with GitHub. We will be u ... ``` -> **Note: if you are using `arm_64` as runner use below to download keploy binary** - -`curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_arm64.tar.gz" | tar xz --overwrite -C /tmp` - ### Example with Scripts While using [express-mongoose](https://github.com/keploy/samples-typescript/tree/main/express-mongoose) sample-application with keploy test in GitHub CI, the workflow would like:- diff --git a/versioned_docs/version-3.0.0/ci-cd/gitlab.md b/versioned_docs/version-3.0.0/ci-cd/gitlab.md index 0ed2341a8..fa574e90c 100644 --- a/versioned_docs/version-3.0.0/ci-cd/gitlab.md +++ b/versioned_docs/version-3.0.0/ci-cd/gitlab.md @@ -41,10 +41,6 @@ keploy-test-job: # This job runs in the test stage. ... ``` -> **Note: if you are using `arm_64` as runner use below to download keploy binary** - -`curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_arm64.tar.gz" | tar xz --overwrite -C /tmp` - Now that we have Keploy installed, and all ready, we need switch to path where `keploy` folder is present in our application and install all the application related dependencies. Since we are using [flask-mongo](https://github.com/keploy/samples-python) sample-application, steps in our `script:` would look like below:- ```yaml @@ -66,17 +62,15 @@ In your `.gitlab-ci.yml file`, in last step we have `keploy test` command to run ### šŸ“ Note -Did you notice some weird stuff in the pipeline? Like `kmod`, `linux-headers`, `/sys/kernel/debug`...and thought, _"Wait, am I hacking the kernel or something?"_ šŸ˜… +Did you notice some weird stuff in the pipeline? Like `kmod`, `linux-headers`, `/sys/kernel/debug` Don’t worry — these are just there because **Keploy uses eBPF** (a cool Linux feature) to trace your app’s behavior. So we install `kmod`, `linux-headers-generic`, and `bpfcc-tools` to make that tracing possible. -Some CI systems don’t have `/sys/kernel/debug` and `/sys/kernel/tracing` by default, so we create them and mount `debugfs` and `tracefs` — it’s like giving Keploy the **backstage pass** it needs to watch your app in action. - -No black magic. Just some low-level Linux stuff helping your tests run like magic! šŸŖ„āœØ +Some CI systems don’t have `/sys/kernel/debug` and `/sys/kernel/tracing` by default, so we create them and mount `debugfs` and `tracefs` -We will get to see output : - +We would output something like below:- ```sh $ keploy test -c "python3 app.py" --delay 50 diff --git a/versioned_docs/version-3.0.0/ci-cd/jenkins.md b/versioned_docs/version-3.0.0/ci-cd/jenkins.md index 6bfad8f9e..77fa60396 100644 --- a/versioned_docs/version-3.0.0/ci-cd/jenkins.md +++ b/versioned_docs/version-3.0.0/ci-cd/jenkins.md @@ -47,10 +47,6 @@ pipeline { ``` -> **Note: if you are using `arm_64` as runner use below to download keploy binary** - -`curl --silent --location "https://github.com/keploy/keploy/releases/latest/download/keploy_linux_arm64.tar.gz" | tar xz --overwrite -C /tmp` - ### Example Now that we have Keploy installed, and all ready, we need switch to path where `keploy` folder is present in our application and install all the application related dependencies. Since we are using [gin-mongo](https://github.com/keploy/samples-go/tree/main/gin-mongo) sample-application, steps in our `script` would look like below:- @@ -106,15 +102,13 @@ pipeline { ### šŸ“ Note -Did you notice some weird stuff in the pipeline? Like `kmod`, `linux-headers`, `/sys/kernel/debug`...and thought, _"Wait, am I hacking the kernel or something?"_ šŸ˜… +Did you notice some weird stuff in the pipeline? Like `kmod`, `linux-headers`, `/sys/kernel/debug` Don’t worry — these are just there because **Keploy uses eBPF** (a cool Linux feature) to trace your app’s behavior. So we install `kmod`, `linux-headers-generic`, and `bpfcc-tools` to make that tracing possible. -Some CI systems don’t have `/sys/kernel/debug` and `/sys/kernel/tracing` by default, so we create them and mount `debugfs` and `tracefs` — it’s like giving Keploy the **backstage pass** it needs to watch your app in action. - -No black magic. Just some low-level Linux stuff helping your tests run like magic! šŸŖ„āœØ +Some CI systems don’t have `/sys/kernel/debug` and `/sys/kernel/tracing` by default, so we create them and mount `debugfs` and `tracefs` We would output something like below:- diff --git a/versioned_docs/version-3.0.0/keploy-cloud/deduplication.md b/versioned_docs/version-3.0.0/keploy-cloud/deduplication.md index 85508fc35..dde0286e4 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/deduplication.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/deduplication.md @@ -1,7 +1,7 @@ --- id: deduplication -title: Remove Duplicates Tests 🧹 -sidebar_label: Remove Duplicate Tests 🧹 +title: Remove Duplicates Tests +sidebar_label: Remove Duplicate Tests tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/keploy-cloud/installation.md b/versioned_docs/version-3.0.0/keploy-cloud/installation.md index e5757cde5..14dc09e16 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/installation.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/installation.md @@ -1,7 +1,7 @@ --- id: cloud-installation title: Keploy Cloud Installation -sidebar_label: Installation šŸ› ļø +sidebar_label: Installation tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/keploy-cloud/keploy-console.md b/versioned_docs/version-3.0.0/keploy-cloud/keploy-console.md index a30f943ff..39150cab6 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/keploy-console.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/keploy-console.md @@ -1,7 +1,7 @@ --- id: keploy-console -title: Keploy Console šŸ“˜ -sidebar_label: Keploy Console šŸ› ļø +title: Keploy Console +sidebar_label: Keploy Console tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/keploy-cloud/mock-registry.md b/versioned_docs/version-3.0.0/keploy-cloud/mock-registry.md index 6cf755de2..f7accea18 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/mock-registry.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/mock-registry.md @@ -1,7 +1,7 @@ --- id: mock-registry title: Mock Registry -sidebar_label: Mock Registry šŸ“¦ +sidebar_label: Mock Registry tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/keploy-cloud/new-application.md b/versioned_docs/version-3.0.0/keploy-cloud/new-application.md index 83c96b361..0222d8e4c 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/new-application.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/new-application.md @@ -3,7 +3,7 @@ id: application-settings title: Keploy Cloud Application Settings Guide description: Learn how to configure application settings in Keploy Cloud. Manage environments, toggle features, and optimize your testing setup with this step-by-step guide. -sidebar_label: Add Application šŸ“ +sidebar_label: Add Application tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/keploy-cloud/testgeneration.md b/versioned_docs/version-3.0.0/keploy-cloud/testgeneration.md index 892d42c48..d699bc505 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/testgeneration.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/testgeneration.md @@ -1,7 +1,7 @@ --- id: auto-test-generation -title: Auto Test Generation šŸš€ -sidebar_label: Test Generation šŸš€ +title: Auto Test Generation +sidebar_label: Test Generation tags: - Auto Test Generation - OpenAPI diff --git a/versioned_docs/version-3.0.0/keploy-cloud/time-freezing.md b/versioned_docs/version-3.0.0/keploy-cloud/time-freezing.md index 5297af402..88b376e9a 100644 --- a/versioned_docs/version-3.0.0/keploy-cloud/time-freezing.md +++ b/versioned_docs/version-3.0.0/keploy-cloud/time-freezing.md @@ -1,7 +1,7 @@ --- id: time-freezing title: Time Freezing -sidebar_label: Time Freezing 🄶 +sidebar_label: Time Freezing tags: - explanation - feature guide diff --git a/versioned_docs/version-3.0.0/quickstart/python-microservices.md b/versioned_docs/version-3.0.0/quickstart/python-microservices.md index 3c72c45b4..e8ed6c27b 100644 --- a/versioned_docs/version-3.0.0/quickstart/python-microservices.md +++ b/versioned_docs/version-3.0.0/quickstart/python-microservices.md @@ -1,7 +1,7 @@ --- id: samples-microservices title: E-commerce Microservices -sidebar_label: Microservices +sidebar_label: E-commerce Microservices description: The following sample microservices app shows how Keploy helps you test microservices applications. In the sample microservices app, we have 3 microservices:user service, product service, and order service, each with its own MySQL database, plus LocalStack SQS for messaging. tags: @@ -25,9 +25,11 @@ keyword: import EnterpriseInstallReminder from '@site/src/components/EnterpriseInstallReminder'; -## Using Docker Compose 🐳 +import CollapsibleCode from '@site/src/components/CollapsibleCode'; -### Introduction +## Keploy Integration testing + +#### Introduction This guide will walk you through testing an E-commerce microservices application with Keploy. The app contains three microservices: @@ -48,11 +50,13 @@ git clone https://github.com/keploy/ecommerce_sample_app.git cd ecommerce_sample_app ``` -_Note: You can view the **architecture diagram** of the application [here](https://keploy-devrel.s3.us-west-2.amazonaws.com/Microservices-architecture.png)_ +_Note: You can view the **architecture diagram** of the application_ + +Sample Keploy Record Microservices #### Start the Microservices -The app is set up with **Docker Compose**, making it easy to start all services together. Let’s begin with the **User Service**. +The app is set up with **Docker Compose**, making it easy to start all services together. Let’s begin with the **Order Service**. ### Capture Test Cases with Keploy @@ -62,11 +66,1029 @@ To start capturing API test cases, use the following command: keploy record -c "docker compose up" --container-name="order_service" --build-delay 40 --path="./order_service" --config-path="./order_service" ``` -Sample Keploy Record Microservices +Sample Keploy Record Microservices + +Now the question arises how to make an API call? We’ve made it simple! You can just import the Postman collection and try sending an API call. + +#### You can download the Postman collection from this URL and import it into Postman: + +```bash +https://github.com/keploy/ecommerce_sample_app/tree/main/postman + +``` + + (or) + +#### If you prefer an easier way, you can simply click the copy full collections button the below. + + 1) pm.environment.set('mouse_id', arr[1].id);", +" }", +" }", +" });", +"}" +], +"type": "text/javascript" +} +} +], +"item": [ +{ +"name": "List products", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products", +"host": [ +"{{product_base}}" +], +"path": [ +"products" +] +} +} +}, +{ +"name": "Get product (laptop)", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}" +] +} +} +}, +{ +"name": "Reserve laptop", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}/reserve", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}", +"reserve" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"quantity\": 1\n}" +} +} +}, +{ +"name": "Release laptop", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}/release", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}", +"release" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"quantity\": 1\n}" +} +} +} +] +}, +{ +"name": "Order Service", +"item": [ +{ +"name": "Create order (laptop x1)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{laptop_id}}\", \"quantity\": 1 } ],\n \"shippingAddressId\": \"{{last_address_id}}\"\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"if (!pm.environment.get('idempotency_key')) { pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}')); }" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created', function(){ pm.expect([200,201]).to.include(pm.response.code); });", +"var j={}; try{ j=pm.response.json(); }catch(e){}; if (j.id){ pm.environment.set('last_order_id', j.id); }" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Create order (fallback default addr)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{mouse_id}}\", \"quantity\": 1 } ]\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}'));" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created', function(){ pm.expect([200,201]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "List my orders", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders?userId={{last_user_id}}&limit=5", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +], +"query": [ +{ +"key": "userId", +"value": "{{last_user_id}}" +}, +{ +"key": "limit", +"value": "5" +} +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('listed', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Get order", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('got order', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Get order details (enriched)", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/details", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"details" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('got details', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Pay order", +"request": { +"method": "POST", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/pay", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"pay" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('paid or already paid', function(){ pm.expect([200].concat([200])).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Cancel order (expect 409 if paid)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/cancel", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"cancel" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('cancel response code', function(){ pm.expect([200,409,404]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Create order idempotent (mouse x2)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{mouse_id}}\", \"quantity\": 2 } ]\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"if (!pm.environment.get('idempotency_key')) { pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}')); }" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created idempotently', function(){ pm.expect([200,201]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +} +] +} +], +"variable": [ +{ +"key": "gw_base", +"value": "http://localhost:8083" +}, +{ +"key": "username", +"value": "alice" +}, +{ +"key": "email", +"value": "alice@example.com" +}, +{ +"key": "user_base", +"value": "http://localhost:8082/api/v1" +}, +{ +"key": "product_base", +"value": "http://localhost:8081/api/v1" +}, +{ +"key": "order_base", +"value": "http://localhost:8080/api/v1" +}, +{ +"key": "jwt", +"value": "" +}, +{ +"key": "last_user_id", +"value": "" +}, +{ +"key": "laptop_id", +"value": "" +}, +{ +"key": "mouse_id", +"value": "" +}, +{ +"key": "idempotency_key", +"value": "" +} +] +} + +... + +` +} + +/> + +**Step 1: If you’ve already downloaded the collection, upload it.** + +Sample Keploy Record Microservices + +**Step 2: Once it is uploaded, you will see the Ecommerce microservices in the left tab.** + +Sample Keploy Record Microservices + +**Step 3: Click the User Service and hit the login URL to get the token.** + +Sample Keploy Record Microservices + +**Step 4: We need to create a user before placing an order. So, create a user using the Create User API.** + +Sample Keploy Record Microservices + +**Step 5: Then, create an address for the user.** + +Sample Keploy Record Microservices + +**Step 6: Once you’re done creating the user details, let’s fetch the product details. This will be helpful when placing an order.\*\*** + +Sample Keploy Record Microservices + +**Step 7: Create an order, but before that, copy the mouse_id to place the order.** + +Sample Keploy Record Microservices -Once the services are up, use the **Postman collection** provided with the app to make some API calls. Keploy will capture these requests and create test cases. +**Step 8: You can verify it using the List Order API.** -You can see in the logs that Keploy starts recording all the network calls. +Sample Keploy Record Microservices + +**Step 9: Once you’ve created an order, use the Payment API to pay for the order.** + +Sample Keploy Record Microservices + +**Step 10: You can use the Get Order API to check the status of your order.** + +Sample Keploy Record Microservices + +> _Note: You can see that Keploy only captures the network calls related to the order service. It can’t capture other network calls because we are recording only for the order service._ Sample Keploy Record microservices @@ -278,32 +1300,1225 @@ spec: restimestampmock: 2025-09-04T11:27:46.162389255Z ``` -## Check Test Coverage +### Run the Tests + +Now, let’s run the tests that were automatically generated by Keploy. Use this command: + +```bash +keploy test -c "docker compose up" --containerName="order_service" --delay 30 --path="./order_service" --config-path="./order_service" +``` + +Sample Keploy Record microservices + +The `--delay` flag gives the app a short pause (in seconds) before running the tests. After the tests finish, you can inspect the results and tweak the test data in the `mocks.yml` or `test-x.yml` files. + +### Check Test Coverage Keploy also helps you track **test coverage** for your app. -The overall coverage report by files: +The coverage files will be generated automatically by Keploy. You can find those files in the coverage directory.Click on any one of the HTML files to see the test coverage. -Sample Keploy test coverage +Sample Keploy test coverage -The overall coverage report by functions: +**Let's see the overall coverage report:** -Sample Keploy test coverage +Sample Keploy test coverage -### Run the Tests +**Let's see the overall coverage report by functions:** -Now, let’s run the tests that were automatically generated by Keploy. Use this command: +Sample Keploy test coverage + +**Once you’ve got the coverage, let’s check the test reports in the Keploy Dashboard.** + +Sample Keploy test coverage + +**Let’s take a look at the Test Reports section.** + +Sample Keploy test coverage + +**Now, let’s go to the individual Test Report section and review the output.** + +Sample Keploy test coverage + +**Two tests have failed — let’s check why they failed.** + +Sample Keploy test coverage + +**From the dashboard, you can see the diff that explains why it failed.** + +_Note: We have just tested only one microservice (Order Service). You can use the same command to test other microservices by changing the name and config path._ + +## Keploy API testing + +#### This section will walk you through testing an E-commerce microservices application using Keploy API Testing. + +We’ll use the Keploy Chrome extension to generate and run API tests — no coding or manual setup required. + +Use the following link to install the [Chrome Extension](https://chromewebstore.google.com/detail/keploy-api-test-recorder/ohcclfkaidblnjnggclkiecgkpgldihe) + +**Note: This extension works only on the Chrome browser. Make sure you’re using Chrome to try it out.** + +Once done, Go to [Keploy Enterprise UI](https://app.keploy.io) to try out Keploy API Testing. Once you sign in, you’ll see a dashboard like this: + +Sample Keploy Record Microservices + +After reaching this step, provide your application URL and the working cURL commands. If the e-commerce application isn’t already running, start it using `docker compose up`. + +**Step 1: Let's provide the curl command in the import curl section** + +Sample Keploy Record Microservices + +Use the following cURL command to import: ```bash -keploy test -c "docker compose up" --containerName="order_service" --delay 30 --path="./order_service" --config-path="./order_service" +curl -X POST -H 'Host: localhost:8080' -H 'Accept-Encoding: gzip, deflate, br' -H 'Connection: keep-alive' -H 'Cache-Control: no-cache' -H 'Accept: */*' -H 'Postman-Token: 682f4ac6-a482-44ab-b7f4-14cd4e8bc989' -H 'User-Agent: PostmanRuntime/7.49.1' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJmMzEwNzA0NC1iYjA1LTExZjAtYTZlMi1hZWVmN2RjNDBlNjYiLCJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNzYyNTAwNzMzLCJleHAiOjE3NjUwOTI3MzN9.pZejD-sAGDMXW9cgGYnS9ReqG-TXFFFnyQZeMMY_2cQ' 'http://localhost:8083/api/v1/orders/d5a441bc-94f6-4695-a30e-4bfdb45d7223/pay' ``` -Sample Keploy Record microservices +**Step 2: Once you provide the input, you will see a response. This means we are able to reach your application and are now ready to generate tests. We’re just performing a validation before generating the test cases.** -The `--delay` flag gives the app a short pause (in seconds) before running the tests. After the tests finish, you can inspect the results and tweak the test data in the `mocks.yml` or `test-x.yml` files. +Sample Keploy Record Microservices -_Note: We have just tested only one microservice (Order Service). You can use the same command to test other microservices by changing the name and config path._ +**Step 3: Next, it’s time to provide the input — such as cURL commands, Postman collections, or an OpenAPI schema. Remember, the more input or content you provide, the better your test cases will be. For this demo, we’ll use Postman collections and cURL commands.** + +Copy this postman collection + + 1) pm.environment.set('mouse_id', arr[1].id);", +" }", +" }", +" });", +"}" +], +"type": "text/javascript" +} +} +], +"item": [ +{ +"name": "List products", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products", +"host": [ +"{{product_base}}" +], +"path": [ +"products" +] +} +} +}, +{ +"name": "Get product (laptop)", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}" +] +} +} +}, +{ +"name": "Reserve laptop", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}/reserve", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}", +"reserve" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"quantity\": 1\n}" +} +} +}, +{ +"name": "Release laptop", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{product_base}}/products/{{laptop_id}}/release", +"host": [ +"{{product_base}}" +], +"path": [ +"products", +"{{laptop_id}}", +"release" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"quantity\": 1\n}" +} +} +} +] +}, +{ +"name": "Order Service", +"item": [ +{ +"name": "Create order (laptop x1)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{laptop_id}}\", \"quantity\": 1 } ],\n \"shippingAddressId\": \"{{last_address_id}}\"\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"if (!pm.environment.get('idempotency_key')) { pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}')); }" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created', function(){ pm.expect([200,201]).to.include(pm.response.code); });", +"var j={}; try{ j=pm.response.json(); }catch(e){}; if (j.id){ pm.environment.set('last_order_id', j.id); }" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Create order (fallback default addr)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{mouse_id}}\", \"quantity\": 1 } ]\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}'));" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created', function(){ pm.expect([200,201]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "List my orders", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders?userId={{last_user_id}}&limit=5", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +], +"query": [ +{ +"key": "userId", +"value": "{{last_user_id}}" +}, +{ +"key": "limit", +"value": "5" +} +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('listed', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Get order", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('got order', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Get order details (enriched)", +"request": { +"method": "GET", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/details", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"details" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('got details', function(){ pm.expect(pm.response.code).to.eql(200); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Pay order", +"request": { +"method": "POST", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/pay", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"pay" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('paid or already paid', function(){ pm.expect([200].concat([200])).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Cancel order (expect 409 if paid)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders/{{last_order_id}}/cancel", +"host": [ +"{{order_base}}" +], +"path": [ +"orders", +"{{last_order_id}}", +"cancel" +] +} +}, +"event": [ +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('cancel response code', function(){ pm.expect([200,409,404]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +}, +{ +"name": "Create order idempotent (mouse x2)", +"request": { +"method": "POST", +"header": [ +{ +"key": "Content-Type", +"value": "application/json" +}, +{ +"key": "Idempotency-Key", +"value": "{{idempotency_key}}" +}, +{ +"key": "Authorization", +"value": "Bearer {{jwt}}" +} +], +"url": { +"raw": "{{order_base}}/orders", +"host": [ +"{{order_base}}" +], +"path": [ +"orders" +] +}, +"body": { +"mode": "raw", +"raw": "{\n \"userId\": \"{{last_user_id}}\",\n \"items\": [ { \"productId\": \"{{mouse_id}}\", \"quantity\": 2 } ]\n}" +} +}, +"event": [ +{ +"listen": "prerequest", +"script": { +"exec": [ +"if (!pm.environment.get('idempotency_key')) { pm.environment.set('idempotency_key', pm.variables.replaceIn('{{$guid}}')); }" +], +"type": "text/javascript" +} +}, +{ +"listen": "test", +"script": { +"exec": [ +"pm.test('order created idempotently', function(){ pm.expect([200,201]).to.include(pm.response.code); });" +], +"type": "text/javascript" +} +} +] +} +] +} +], +"variable": [ +{ +"key": "gw_base", +"value": "http://localhost:8083" +}, +{ +"key": "username", +"value": "alice" +}, +{ +"key": "email", +"value": "alice@example.com" +}, +{ +"key": "user_base", +"value": "http://localhost:8082/api/v1" +}, +{ +"key": "product_base", +"value": "http://localhost:8081/api/v1" +}, +{ +"key": "order_base", +"value": "http://localhost:8080/api/v1" +}, +{ +"key": "jwt", +"value": "" +}, +{ +"key": "last_user_id", +"value": "" +}, +{ +"key": "laptop_id", +"value": "" +}, +{ +"key": "mouse_id", +"value": "" +}, +{ +"key": "idempotency_key", +"value": "" +} +] +} + +... + +` +} + +/> + +Paste the collections in the postman collections section. + +Sample Keploy Record Microservices + +**Also copy the curl commands:** + + + +Paste the cURL commands in the cURL section. + +Sample Keploy Record Microservices + +**Step 4: Before generating the test, review and confirm the generation settings. In this example, the port has been changed to 8083, meaning the application gateway runs on 8083 to access all the services.** + +Sample Keploy Record Microservices + +**Step 5: After completing the previous steps, click the Generate API Test button to automatically create test cases for your application.** + +Sample Keploy Record Microservices + +**Step 6: You can see the test suites created by Keploy. Click on an individual test suite to view the request, response, and variables.** + +Sample Keploy Record Microservices + +**Step 7: To visualize the steps, click the Visualize button. This will display a visual representation of the test flow.** + +Sample Keploy Record Microservices + +**Step 8: One of the test suites is marked as buggy. This means our application has some issues that Keploy detected. If you’re sure it’s not actually buggy, you can mark it as ā€˜Not Buggy.** + +Sample Keploy Record Microservices + +**Step 9: After generating the test, click the Run Tests button to execute it.** + +Sample Keploy Record Microservices ## Conclusion šŸŽ‰ -Well done! You’ve seen how Keploy helps test your microservices without writing any code. You've generated test cases, run tests, and checked coverage—all with just a few commands. Keep experimenting and enhancing your tests to ensure your app’s reliability. +Well done! You’ve seen how Keploy helps test your microservices without writing any code. You've generated test cases, run tests, and checked coverage—all with just a few commands. diff --git a/versioned_sidebars/version-3.0.0-sidebars.json b/versioned_sidebars/version-3.0.0-sidebars.json index c1113be04..5a04f7876 100644 --- a/versioned_sidebars/version-3.0.0-sidebars.json +++ b/versioned_sidebars/version-3.0.0-sidebars.json @@ -177,7 +177,7 @@ { "type": "category", "label": "Keploy Enterprise", - "collapsed": true, + "collapsed": false, "items": [ { "type": "category", @@ -205,7 +205,7 @@ }, { "type": "doc", - "label": "Common Erros", + "label": "Troubleshooting Guide", "id": "keploy-explained/common-errors" }, {