Skip to content

Pythagora-io/pythagora

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
March 29, 2023 09:53

Text changing depending on mode. Light: 'So light!' Dark: 'So dark!'

Developers spend 20-30% of their time writing tests!

With Pythagora, devs spend 0.2% time on tests while having 100% code coverage w/ negative tests


Pythagora is a dev tool that generates integration tests for web apps by recording server activity without you having to write a single line of code


๐Ÿ” Pythagora creates detailed integration tests that check API response, database queries and responses, 3rd party API requests and more ๐Ÿ”


๐Ÿ’ฏ Within a couple of hours of playing around your app while Pythagora capturing is on, you can cover your codebase with 100% code coverage ๐Ÿ’ฏ


๐Ÿฆธ You donโ€™t need to think about covering edge cases since our GPT-4 integration creates negative tests to superpower your test suite ๐Ÿฆธ


๐ŸŽš If you have a QA team, you can easily give them access to creating automated tests for backend with Pythagora ๐ŸŽš



Pythagora Alpha Demo

๐ŸŽž๏ธ โ–ถ๏ธ Video resources โ–ถ๏ธ ๐ŸŽž๏ธ

Pythagora Demo (4 min)
Pythagora Tech Deep Dive (16 min)
Dev Workflow With Pythagora (4 min)

๐Ÿ—๏ธ How it works

To integrate Pythagora into your Node.js app, you just need to install the pythagora package

npm install pythagora

and run the Pythagora capture command. Then, just play around with your app and from all API requests and database queries Pythagora will generate integration tests.

1. Capturing requests

Pythagora records all requests to endpoints of your app with the response and everything that's happening during the request. Currently, that means all Mongo and Redis queries with responses (in the future 3rd party API requests, disk IO operations, etc.). Then, when you run the tests, Pythagora can simulate the server conditions from the time when the request was captured.

2. Running tests

When running tests, it doesnโ€™t matter what database is your Node.js connected to or what is the state of that database. Actually, that database is never touched or used โ€”> instead, Pythagora creates a special, ephemeral `pythagoraDb` database, which it uses to restore the data before each test is executed, which was present at the time when the test was recorded. Because of this, tests can be run on any machine or environment.

If a test does an update to the database, Pythagora also checks the database to see if it was updated correctly.

โš™๏ธ Setup

  1. Install Pythagora by running

    npm install pythagora
    And that's it! You are ready to start recording your integration tests!

๐ŸŽฅ Capturing tests

  1. From the root directory run Pythagora in a capture mode first to capture test data and mocks.

    npx pythagora --init-command "my start command" --mode capture
    Eg. if you start your Node.js app with nest start then the command would be:

    npx pythagora --init-command "nest start" --mode capture
  2. Click around your application or make requests to your API. Pythagora will capture all requests and responses.

    NOTE: To stop the capture, you can exit the process like you usually do (Eg. Ctrl + C)

โ–ถ๏ธ Executing tests

After you captured all requests you want, you just need to change the mode parameter to --mode test in the Pythagora command.

npx pythagora --init-command "my start command" --mode test



๐Ÿ“– Options

These are available options for Pythagora command:


--rerun-all-failed (runs again only tests that failed in previous run)

npx pythagora --init-command "my start command" --mode test --rerun-all-failed

--delete-all-failed (deletes all previously failed tests)

npx pythagora --init-command "my start command" --delete-all-failed

--delete testId (deletes test with testId)

npx pythagora --init-command "my start command" --delete testId

--pick endpoint1 endpoint2 (starts capturing only listed endpoints)

npx pythagora --init-command "my start command" --mode capture --pick /endpoint1 /endpoint2

--ignore endpoint1 endpoint2 (starts capturing but ignores all listed endpoints)

npx pythagora --init-command "my start command" --mode capture --ignore /endpoint1 /endpoint2

--review (runs review process of failed tests, allowing you to update old captured tests or to delete them)

npx pythagora --review



๐Ÿ“ Code Coverage Report

Code coverage is a great metric while building automated tests as it shows us which lines of code are covered by the tests. Pythagora uses nyc to generate a report about code that was covered with Pythagora tests. By default, Pythagora will show you the basic code coverage report summary when you run tests.

If you want to generate a more detailed report, you can do so by running Pythagora with --full-code-coverage-report flag. Eg.

npx pythagora --init-command "my start command" --mode test --full-code-coverage-report

You can find the code coverage report inside pythagora_tests folder in the root of your repository. You can open the HTML view of the report by opening pythagora_tests/code_coverage_report/lcov-report/index.html.


In case you don't want the code coverage to be shown at all while running tests, you can run the tests with --no-code-coverage parameter. This is helpful during debugging process since the code coverage report can clash with your IDE's debugger.



๐Ÿ”‘ Authentication

For authentication we support JWT, sessions stored in Redis and sessions stored in MongoDB. First 2 cases cases (JWT and sessions stored in Redis) should work just fine without any additional implementation but for session that are stored in MongoDB you need to add this one line of code:
if (global.Pythagora) global.Pythagora.authenticationMiddleware = true;

just before your authentication middleware. For example, if you are using express-session you would have to add our line of code just above your middleware that is managing sessions in your DB, like this:

if (global.Pythagora) global.Pythagora.authenticationMiddleware = true;

app.use(session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 60 * 60 * 1000
    },
    store: MongoStore.create({
        mongoUrl: mongourl,
        mongoOptions: {
            useNewUrlParser: true,
            useUnifiedTopology: true
        }
    })
}));

That's it! You are ready to go and all your API requests with authentication should PASS!



๐Ÿ—บ๏ธ๏ธ Where can I see the tests?

Each captured test is saved in pythagora_tests directory at the root of your repository. Each JSON file in this repository represents one endpoint that was captured and each endpoint can have many captured tests. If you open these files, you will see an array in which each object represents a single test. All data that's needed to run a test is stored in this object. Here is an example of a test object.
{
   "id": "b47cbee2-4a47-4b2c-80a0-feddae3081b3",
   "endpoint": "/api/boards/", // endpoint that was called
   "body": {}, // body payload that was sent with the request
   "query": {}, // query params that were sent with the request
   "params": {}, // params that were sent with the request
   "method": "GET", // HTTP method that was used
   "headers": { // headers that were sent with the request
      "x-forwarded-host": "localhost:3000",
      ...
   },
   "statusCode": 200, // status code that was returned
   "responseData": "...", // response data that was received
   "intermediateData": [ // server activity that was captured during the request
      {
         "type": "mongodb", // type of the activity - mongo query in this case
         "op": "findOneAndUpdate",
         "db": "ecomm",
         "collection": "users",
         "query": { // mongo match query that was executed
            "_id": "ObjectId(\"63f5e8272c78361761e9fcf1\")"
         },
         "otherArgs": {
            "update": { // data that needs to be updated
               "$set": {
                  "name": "Steve",
                  ...
               }
            },
            ...
         },
         "options": {
            "upsert": false,
            ...
         },
         "preQueryRes": [ // data that was present in the database before the query was executed
            {
               "_id": "ObjectId(\"63f5e8272c78361761e9fcf1\")",
               "name": "Michael",
               ...
            }
         ],
         "mongoRes": [ // data that was returned by the query
            {
               "_id": "ObjectId(\"63f5e8272c78361761e9fcf1\")",
               "name": "Steve",
               ...
            }
         ],
         "postQueryRes": [ // data that was present in the database after the query was executed
            {
               "_id": "ObjectId(\"63f5e8272c78361761e9fcf1\")",
               "name": "Steve",
               ...
            }
         ]
      }
   ],
   "createdAt": "2023-02-22T14:57:52.362Z" // date when the test was captured
}



โ›‘๏ธ Support

For now, we support projects that use:

Other technologies that Pythagora works with:

Apollo server GraphQL NestJS Next.js Nuxt.js PostgreSQL
Logo 1 Logo 2 Logo 3 Logo 1 Logo 1 Logo 1
โœ… โœ… โœ… Upcoming Upcoming Upcoming

๐Ÿ Alpha version

This is an alpha version of Pythagora. To get an update about the beta release or to give a suggestion on tech (framework / database) you want Pythagora to support you can ๐Ÿ‘‰ add your email / comment here ๐Ÿ‘ˆ .


๐Ÿ”— Connect with us

๐Ÿ’ฌ Join the discussion on our Discord server.

๐Ÿ“จ Get updates on new fetures and beta release by adding your email here.

โญ Star this repo to show support.