Skip to content

di-sukharev/AI-TDD

master
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

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
September 11, 2023 15:25
November 26, 2023 12:38
src
November 26, 2023 16:31
November 30, 2023 21:33
November 26, 2023 15:47
November 26, 2023 18:57
November 26, 2023 16:06
:(
November 26, 2023 18:42
aitdd logo

AI + TDD

Follow the bird

GPT powered CLI for TDD

You write the test — GPT writes the code until it passes the test ✅

Prompting GPT with a test suite makes it write code impressively accurate


Setup

AITDD runs on Bun, make sure you first install the latest Bun version.

  1. Install AITDD globally as a CLI:

    curl -sSL https://raw.githubusercontent.com/di-sukharev/AI-TDD/master/install.sh | bash
  2. Get your API key from OpenAI. Make sure you add payment details, so API works.

  3. Set the key to AITDD config:

    aitdd config set OPENAI_API_KEY <your_api_key>

    Your api key is stored locally in ~/.aitdd/config config file and is not stored anywhere in any other way.

  4. Set the command to run the tests:

    aitdd config set RUN_TESTS "npm run test"

Your api key is stored locally in ~/.aitdd/config config file and is not stored anywhere in any other way.

Example

Here is a frontend test suite written in Jest + Testing Library. Yes, AITDD easily passes even frontend tests:

import React from "react";
import { rest } from "msw";
import { setupServer } from "msw/node";
import { render, fireEvent, waitFor, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import Fetch from "../fetch";

const server = setupServer(
  rest.get("/greeting", (req, res, ctx) => {
    return res(ctx.json({ greeting: "hello there" }));
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test("loads and displays greeting", async () => {
  render(<Fetch url="/greeting" />);

  fireEvent.click(screen.getByText("Load Greeting"));

  await waitFor(() => screen.getByRole("heading"));

  expect(screen.getByRole("heading")).toHaveTextContent("hello there");
  expect(screen.getByRole("button")).toBeDisabled();
});

test("handles server error", async () => {
  server.use(
    rest.get("/greeting", (req, res, ctx) => {
      return res(ctx.status(500));
    })
  );

  render(<Fetch url="/greeting" />);

  fireEvent.click(screen.getByText("Load Greeting"));

  await waitFor(() => screen.getByRole("alert"));

  expect(screen.getByRole("alert")).toHaveTextContent("Oops, failed to fetch!");
  expect(screen.getByRole("button")).not.toBeDisabled();
});

Ready? Here is the code generated by AITDD (GPT-4) to pass the test:

import React, { useState } from "react";

function Fetch({ url }) {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);

  async function fetchData() {
    setLoading(true);
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error("Failed to fetch");
      const data = await response.json();
      setData(data.greeting);
    } catch (error) {
      setError(error.message);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      {data && <h1 role="heading">{data}</h1>}
      {error && <div role="alert">{error}</div>}
      <button onClick={fetchData} disabled={loading}>
        Load Greeting
      </button>
    </div>
  );
}

export default Fetch;

Usage

You can call aitdd like this:

aitdd run

Payments

You pay for your own requests to OpenAI API. AITDD uses latest GPT model by default, check it's pricing. Maximum response tokens are set to 2000, you can adjust it via ait config set maxTokens=<number>.

I couldn't manage ChatGPT model to solve the problem. I tried to few shot it with a response example, it doesn't understand what I want. If you want to try manage it via ChatGPT — test it and open a PR 🚀