Not writing unit tests ("Testing is QA's job")
Unit Testing? That's QA's Problem, What Does It Have to Do with Me? If the code runs, that's enough. Testing is the testing team's job, and writing unit tests only slows down development. If you think this way, congratulations—you've mastered the essence of "defensive programming": how to make code unmaintainable. Here are some classic moves guaranteed to drive your colleagues and your future self crazy.
"Elegant" Ways to Avoid Unit Testing
1. Directly Call Production APIs
Why mock data in a test environment? Just call the production API directly—it saves time! For example, when writing a user login function, call the production login API directly and skip mocking altogether:
async function login(username, password) {
const response = await fetch('https://production-api.com/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
});
return response.json();
}
The "benefits" of this approach:
- You might crash the production database during testing;
- Every test requires real credentials, which is great for "security testing";
- If the API goes down, your tests fail too—killing two birds with one stone.
2. Tightly Couple Logic and UI
Mix business logic with UI code to make testing impossible. For example, a button click handler that directly modifies the DOM and sends a request:
document.getElementById('submit-btn').addEventListener('click', () => {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
fetch('https://api.com/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
})
.then(response => response.json())
.then(data => {
document.getElementById('result').innerHTML = `Welcome, ${data.user.name}!`;
})
.catch(() => {
document.getElementById('result').innerHTML = 'Login failed!';
});
});
The "advantages" of this code:
- You can't test the login logic in isolation—you have to spin up the entire page;
- UI changes directly cause tests to fail;
- Want to write unit tests? Better learn Puppeteer first!
3. Rely on Global State
Make functions depend entirely on global variables to ensure chaotic test states. For example:
let isLoggedIn = false;
function toggleLogin() {
isLoggedIn = !isLoggedIn;
console.log(`Current login status: ${isLoggedIn}`);
}
Testing this code requires:
- Manually resetting
isLoggedIn
; - Praying no other test case modifies it;
- Enjoying the "random surprises" of test order affecting results.
4. Ignore Edge Cases
Edge cases? That's the user's problem. For example, a price calculation function:
function calculatePrice(quantity, price) {
return quantity * price;
}
The "elegance" lies in:
- User passes
quantity = -1
? Return a negative price and confuse accounting; - User passes
price = 'abc'
? ReturnNaN
and let the frontend display "NaN dollars"; - Testing? Unnecessary—users will find all the bugs for you.
5. Use "Magic Numbers" Instead of Constants
Hardcode numbers or strings directly into the code to leave maintainers guessing. For example:
function getDiscount(price) {
if (price > 1000) {
return price * 0.1; // What is 0.1? Who knows?
}
return 0;
}
"Advanced" techniques:
- Don't write comments—let future developers figure it out;
- When modifying the discount, remember to globally search for
0.1
; - Test coverage? This kind of code is untestable by design.
"Black Magic" to Make Testing Tools Useless
1. Use Randomness
Insert random behavior into core logic to make test results unpredictable:
function shouldOfferDiscount() {
return Math.random() > 0.5; // 50% chance of a discount—surprise!
}
Testing this function:
- First run passes, second run fails;
- Use
jest.spyOn(Math, 'random')
? Too much trouble—just give up; - Final report: "50% test pass rate."
2. Depend on External Time
Make function behavior depend on the current time, for example:
function isPromotionAvailable() {
const hour = new Date().getHours();
return hour >= 20; // Promotion available after 8 PM
}
Testing this requires:
- Manually changing the system time;
- Using
jest.useFakeTimers()
? Too complicated; - Testing late at night to enjoy "time synchronization" fun.
3. Side Effects Everywhere
Let functions secretly modify external state, for example:
const userCache = {};
function getUser(id) {
fetch(`https://api.com/users/${id}`)
.then(response => response.json())
.then(data => {
userCache[id] = data; // Sneakily modify the cache
});
}
The "charm" of this code:
- Testing
getUser
suddenly changesuserCache
; - Impossible to verify function behavior via input/output;
- Test cases pollute each other—exciting like Russian roulette.
The Ultimate Art: Make Future Developers Fear Your Code
1. Write "Self-Destruct" Code
Plant time bombs in your code, for example:
function processPayment(amount) {
if (amount > 10000) {
throw new Error('Amount too large—suspected hacker attack!');
}
// Actual payment logic
}
"Safety" measures:
- Testing large payments? Immediate error;
- Future developers won't dare modify the logic, fearing the "security mechanism";
- Production issues? Blame it on untested edge cases.
2. Use "Hyper-Dynamic" Logic
Use eval
or dynamic property names to break static analysis tools:
function getConfigValue(key) {
return eval(`config.${key}`); // Who dares refactor this?
}
"Dynamic" advantages:
- IDE can't jump to definitions;
- No way to know possible
key
values during testing; - Code security scanners will freak out—adding a sense of security.
3. Reject Documentation and Types
Skip JSDoc and TypeScript to let future developers "freestyle":
function mergeData(a, b) {
return { ...a, ...b };
}
"Flexibility" highlights:
a
andb
can be anything;- Testing must account for
a=null
,b=undefined
,a=123
, etc.; - Future developers spend a week guessing parameter types.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn