Skip to main content
Okay — last but certainly not least: Cursor. Cursor is a standalone editor (a fork of Visual Studio Code) rather than a VS Code extension. If you’ve used VS Code, the UI will feel familiar, but Cursor packages the editor, chat/composer, and generation features into a single, contained window. That creates an immersive experience where the coding UI and AI-driven composer/chat are tightly integrated. Quick UI and command highlights:
  • Open the Composer / command palette with Ctrl+I (or Cmd+I on macOS).
  • The Composer exposes commands such as Add Files, Edit, Refactor, Add Code, and switching models (e.g., Claude 3.5 Sonnet, GPT-4o family, Cursor Small).
  • Some keybindings are intercepted by Cursor and won’t be forwarded to the terminal by default. You can rebind them if required.
A dark-themed code editor on macOS with a small Composer/chat popup in the center showing "Generating." The left sidebar shows a project folder named "MARKDOWNTOTHTML."
We used Cursor’s Composer to scaffold a small Python project. Cursor generated a project structure, template files, a sensible .gitignore, pyproject.toml, a basic main application, and a test skeleton. Below are the key generated artifacts, the improved code, and practical tips to run and test the project reliably.

What Cursor generated (at a glance)

Generated .gitignore

Cursor created a standard Python .gitignore. Only one copy is shown here.

Project metadata (pyproject.toml)

Cursor generated a minimal pyproject.toml using hatchling and included common dev dependencies:

Example requirements.txt

Cursor added example runtime and development dependencies to requirements.txt:

main.py — scaffolded and improved

Cursor scaffolded a main entrypoint with logging. We refactored the file-processing logic into a standalone function to make it easier to test and more robust. Important fixes included: open the output file once (not inside the loop) and return processed lines for testability. Final recommended version:
Notes:
  • Opening the output file once and writing per-line prevents repeatedly truncating the file.
  • Returning the processed lines makes unit testing straightforward.

Example config.py

Cursor added a small config helper to read environment variables (common for API keys and configuration). Typically this file uses os.environ or python-dotenv to load values and keep secrets out of source control.

Create a virtual environment, install dependencies, and run

From your project root, follow these steps:
If you see an error like “can’t open file … src/main.py: [Errno 2] No such file or directory”, verify the path — in this scaffold the main file lives at src/my_project/main.py.

Cursor Composer: generating quick code and files

Cursor’s Composer can generate small helper snippets and files (e.g., a demo demo.txt or a function that reads a file). A typical iterative workflow:
  • Use the Composer to create demo.txt with Lorem Ipsum or sample lines.
  • Ask Cursor to “Open demo.txt and print it line by line” and accept the generated snippet.
  • Use the Composer to refactor code (for example, “Move this into a function”) and accept a suggested refactor.
  • Always review generated code — fix minor issues such as indentation, function placement, or file-handling correctness.
AI-generated code is fast, but human review prevents subtle bugs.

Writing a proper unit test

Cursor generated a basic test skeleton. We updated it to match the refactored process_file signature and to use pytest fixtures (tmp_path) so tests are deterministic and isolated from the repository. Example tests/tests_main.py:
Test design tips:
  • Use tmp_path to avoid touching repository files and ensure tests run in isolation.
  • Call process_file with explicit temporary paths to avoid side effects.
  • Assert both the returned result and the output file contents.

Common testing / packaging issues and fixes

When running tests you may encounter import errors like “ModuleNotFoundError: No module named ‘my_project’”. Typical fixes:
  1. Install your package in editable mode from the project root:
This ensures my_project is importable by pytest.
  1. Ensure package structure is configured correctly. If you rely on implicit namespace packages, adjust pyproject.toml; otherwise add an __init__.py:
  1. Verify pytest configuration ([tool.pytest.ini_options]) points to the tests folder and the expected test filename patterns (the generated pyproject.toml already contains sensible defaults).
After addressing imports and installing the package in editable mode, run tests with:
A successful run will show collected tests and a green result.

Debugging loops and where developer judgment matters

AI-assisted tools like Cursor can scaffold code, suggest fixes, and accelerate iteration, but they can also create back-and-forth edit loops (changed APIs, import paths, test mismatches). During this exercise we intentionally ran into loop-like issues (module import paths, function signatures vs. tests) to demonstrate how developer knowledge resolves structural problems.
AI tools accelerate scaffolding and routine edits, but keep an eye on:
  • Project structure and package/module paths
  • Function signatures vs. tests (ensure tests reflect actual function APIs)
  • File handling (open output files once, not inside loops)
Cursor is particularly useful for quick generation (dummy files, simple refactors, test skeletons) and for integrating terminal errors into an iterative chat. If you find yourself stuck in a loop, try switching models or step back to verify the fundamentals: package layout, pyproject.toml configuration, and import paths. We’ll expand this into a larger application and combine multiple tools (ChatGPT, Tabnine, BlackboxAI, Cursor) to show a broader, integrated AI-assisted development workflow.

Watch Video