alepha@docs:~/docs/guides/testing$
cat 2-rules.md
2 min read
Last commit:

#Test Naming Rules

Good test names are documentation. Bad test names are noise.

These 10 rules will make your tests readable, debuggable, and maintainable.

Source: Frontend Testing Guide: 10 Essential Rules

#Rule 1: Always Use "should" + Verb

Every test name should start with "should" followed by an action verb.

js
1// Bad2it("displays the error message", () => {});3it("modal visibility", () => {});4it("form validation working", () => {});5 6// Good7it("should display error message when validation fails", () => {});8it("should show modal when trigger button is clicked", () => {});9it("should validate form when user submits", () => {});

Pattern: should [verb] [expected outcome]

#Rule 2: Include the Trigger Event

Specify what causes the behavior you're testing.

js
1// Bad2it("should update counter", () => {});3it("should validate email", () => {});4it("should show dropdown", () => {});5 6// Good7it("should increment counter when plus button is clicked", () => {});8it("should show error when email format is invalid", () => {});9it("should open dropdown when toggle is clicked", () => {});

Pattern: should [verb] [expected outcome] when [trigger event]

#Rule 3: Group Related Tests with Descriptive Contexts

Use describe blocks to create clear test hierarchies.

js
 1// Bad 2describe("AuthForm", () => { 3  it("should test empty state", () => {}); 4  it("should test invalid state", () => {}); 5  it("should test success state", () => {}); 6}); 7  8// Good 9describe("AuthForm", () => {10  describe("when form is empty", () => {11    it("should disable submit button", () => {});12    it("should not show any validation errors", () => {});13  });14 15  describe("when submitting invalid data", () => {16    it("should show validation errors", () => {});17    it("should keep submit button disabled", () => {});18  });19});

Pattern:

js
1describe("[Component/Feature]", () => {2  describe("when [specific condition]", () => {3    it("should [expected behavior]", () => {});4  });5});

#Rule 4: Name State Changes Explicitly

Clearly describe the before and after states in your test names.

js
1// Bad2it("should change status", () => {});3it("should update todo", () => {});4it("should modify permissions", () => {});5 6// Good7it("should change status from pending to approved", () => {});8it("should mark todo as completed when checkbox clicked", () => {});9it("should upgrade user from basic to premium", () => {});

Pattern: should change [attribute] from [initial state] to [final state]

#Rule 5: Describe Async Behavior Clearly

Include loading and result states for asynchronous operations.

js
1// Bad2it("should load data", () => {});3it("should handle API call", () => {});4it("should fetch user", () => {});5 6// Good7it("should show skeleton while loading data", () => {});8it("should display error message when API call fails", () => {});9it("should render profile after user data loads", () => {});

Pattern: should [verb] [expected outcome] [during/after] [async operation]

#Rule 6: Name Error Cases Specifically

Be explicit about the type of error and what causes it.

js
1// Bad2it("should show error", () => {});3it("should handle invalid input", () => {});4it("should validate form", () => {});5 6// Good7it('should show "Invalid Card" when card number is wrong', () => {});8it('should display "Required" when password is empty', () => {});9it("should show network error when API is unreachable", () => {});

Pattern: should show [specific error message] when [error condition]

#Rule 7: Use Business Language, Not Technical Terms

Write tests using domain language rather than implementation details.

js
1// Bad2it("should update state", () => {});3it("should dispatch action", () => {});4it("should modify DOM", () => {});5 6// Good7it("should save customer order", () => {});8it("should update cart total", () => {});9it("should mark order as delivered", () => {});

Pattern: should [business action] [business entity]

#Rule 8: Include Important Preconditions

Specify conditions that affect the behavior being tested.

js
1// Bad2it("should enable button", () => {});3it("should show message", () => {});4it("should apply discount", () => {});5 6// Good7it("should enable checkout when cart has items", () => {});8it("should show free shipping when total exceeds $100", () => {});9it("should apply discount when user is premium member", () => {});

Pattern: should [expected behavior] when [precondition]

#Rule 9: Name UI Feedback Tests from User Perspective

Describe visual changes as users would perceive them.

js
1// Bad2it("should set error class", () => {});3it("should toggle visibility", () => {});4it("should update styles", () => {});5 6// Good7it("should highlight search box in red when empty", () => {});8it("should show green checkmark when password is strong", () => {});9it("should disable submit button while processing", () => {});

Pattern: should [visual change] when [user action/condition]

#Rule 10: Structure Complex Workflows Step by Step

Break down complex processes into clear steps.

js
 1// Bad 2describe("Checkout", () => { 3  it("should process checkout", () => {}); 4  it("should handle shipping", () => {}); 5  it("should complete order", () => {}); 6}); 7  8// Good 9describe("Checkout Process", () => {10  it("should first validate items are in stock", () => {});11  it("should then collect shipping address", () => {});12  it("should finally process payment", () => {});13 14  describe("after successful payment", () => {15    it("should display order confirmation", () => {});16    it("should send confirmation email", () => {});17  });18});

Pattern:

js
1describe("[Complex Process]", () => {2  it("should first [initial step]", () => {});3  it("should then [next step]", () => {});4  it("should finally [final step]", () => {});5 6  describe("after [key milestone]", () => {7    it("should [follow-up action]", () => {});8  });9});

#Complete Example

Here's a comprehensive example showing how to combine all these rules:

js
 1// Bad 2describe("ShoppingCart", () => { 3  it("test adding item", () => {}); 4  it("check total", () => {}); 5  it("handle checkout", () => {}); 6}); 7  8// Good 9describe("ShoppingCart", () => {10  describe("when adding items", () => {11    it("should add item to cart when add button is clicked", () => {});12    it("should update total price immediately", () => {});13    it("should show item count badge", () => {});14  });15 16  describe("when cart is empty", () => {17    it("should display empty cart message", () => {});18    it("should disable checkout button", () => {});19  });20 21  describe("during checkout process", () => {22    it("should validate stock before proceeding", () => {});23    it("should show loading indicator while processing payment", () => {});24    it("should display success message after completion", () => {});25  });26});

#Checklist

Before committing your test, verify that its name:

  • Starts with "should"
  • Uses a clear action verb
  • Specifies the trigger condition
  • Uses business language
  • Describes visible behavior
  • Is specific enough for debugging
  • Groups logically with related tests
On This Page
No headings found...
ready
mainTypeScript
UTF-8guides_testing_rules.md