revops
Design and optimize systems connecting marketing, sales, and customer success into a unified revenue engine.
Enforce the Iron Law of TDD for Frappe apps. Red-Green-Refactor cycle for DocTypes and Controllers.
Full skill instructions
"Write the test first. Watch it fail. Write minimal code to pass."
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.
If you write code before the test: Delete it. Start over. This is non-negotiable.
Write one minimal test showing what should happen. Use FrappeTestCase.
import frappe
from frappe.tests.utils import FrappeTestCase
class TestSalesOrder(FrappeTestCase):
def test_status_must_be_draft_on_creation(self):
# We wish for this behavior
doc = frappe.get_doc({"doctype": "Sales Order", "customer": "Test Customer"})
self.assertEqual(doc.status, "Draft")
Verify RED: Run bench --site [site] run-tests --doctype "Sales Order".
doc.status is NOT "Draft".Write the simplest code in the controller (sales_order.py) to pass the test.
class SalesOrder(Document):
def before_insert(self):
self.status = "Draft"
Verify GREEN: Run the test again. It must pass.
Clean up duplication, improve names, or extract helpers while keeping the test Green.
def test_customer_is_mandatory(self):
doc = frappe.get_doc({"doctype": "Sales Order", "customer": None})
self.assertRaises(frappe.ValidationError, doc.insert)
def test_regular_user_cannot_submit(self):
frappe.set_user("[email protected]")
doc = frappe.get_doc("Sales Order", "SO-001")
self.assertRaises(frappe.PermissionError, doc.submit)
Prefer real data using frappe.get_doc. If you must mock external APIs:
from unittest.mock import patch
@patch('frappe.make_get_request')
def test_api_integration(self, mock_get):
mock_get.return_value = {"status": "success"}
# ... call your method ...
| Avoid | Why | Instead |
|---|---|---|
| Test After | Fails to prove the test actually works. | Test First. |
| Manual Cleanup | Error-prone and slow. | Use frappe.db.rollback() in tearDown. |
| Huge Setups | Makes tests hard to read. | Use frappe.get_test_records(). |
| Mocking Frappe | Mocks don't test the DB state. | Use the real frappe.db in FrappeTestCase. |
tearDown performs rollback or cleanup.Design and optimize systems connecting marketing, sales, and customer success into a unified revenue engine.
Strategic planning and optimization for email capture offers and gated content.
Directory submissions: the foundation layer of distribution that passes backlinks and discovery surface area into your marketing pages.
Sequence and choreograph multi-step animations with precise timing control and nested timelines.
Structured framework for planning product launches, feature announcements, and go-to-market strategies.
Upload files to Google Drive with automatic MIME type detection and metadata.
Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.
firecrawl lead gen
firecrawl lead research
firecrawl demo walkthrough
Team leadership persona with standup coordination, meeting prep, task delegation, and team communication.
Identify large Google Drive files consuming storage quota.
Revolutionize Video Creation with AI-Generated Avatars and Voices
Social media on autopilot
Design custom logos instantly with AI.
Text-heavy marketing and design images
Boost Your SEO with Content and SEO Silos
Revolutionize Your Marketing with AI-Powered MarketingBlocks!
10X faster & free AI content creation for 100+ use cases
Tribescaler | Make Your Tweets Go Viral