Traditionally developers only write unit tests (hopefully!) and QA engineers write System tests, with Selenium or some other tool. However, while this separation has some reasons, it's also a bit arbitrary and unhealthy. In this talk we'll discuss why you should be involved in all kinds of test automation and discuss best practices for utilizing the test automation to improve the development lifecycle, as well as both the internal and the external quality of your code.
7. Some common (mis?)conceptions
Unit System
Purpose Verify implementation Find bugs
Planned, written and used by Developers Testers / Automation Developers
Runs After Check-in Nightly / Before release
Scope Single function or class Entire System (Like a real user)
Isolation Mock all I/O (DB, Network, etc.) Full environment
Data Fake Real
Stability High Low
Speed Very fast Very slow
Failure investigation Easy Hard
When written Before (TDD?) Only when dev is done
25. “Refactoring is all about applying small
behavior-preserving steps and making a big
change by stringing together a sequence of
these behavior-preserving steps … As a
result, when I’m refactoring, my code doesn’t
spend much time in a broken state, allowing
me to stop at any moment even if I haven’t
finished.”
27. 4 Rules of Simple Design / Kent Beck
Passes all the Tests
Reveals the intention
No duplication
Fewest elements (functions and
methods)
The rules are in priority order
33. Test Method Example
[TestMethod]
public void AddingProductWithPromotionGivesDiscount()
{
const decimal price = 1200;
const decimal discount = 150;
var iPhone = CreateProduct("iPhone", price);
CreatePromotionOnProduct(iPhone, discount);
var shoppingCart = CreateShoppingCart();
shoppingCart.Add(iPhone);
Assert.AreEqual(price - discount, shoppingCart.Total);
}
34. Best Practices for Writing Tests
Keep it simple
Reliability
Isolate tests from one another
Deterministic and Specific Expected Result
Don’t assume anything about existing data
Mock anything you can’t control
Maintainability
Readable
No duplication
Refactor continuously!
35. ATDD - Acceptance Test Driven Development
PO defines the problem (User Story)
PO & team collaborate on simplest solution
Define Acceptance Criteria
Implement automated test
Implement Code & Refactor
Exploratory testing
Get customer feedback
36. Back to our (mis)conceptions…
Unit System
Purpose Verify implementation Find bugs
Planned, written and used by Developers Testers / Automation Deelopers
Runs After Check-in Nightly / Before release
Scope Single function or class Entire System (Like a real user)
Isolation Mock all I/O (DB, Network, etc.) Full environment
Data Fake Real
Stability High Low
Speed Very fast Very slow
Failure investigation Easy Hard
When written Before (TDD?) Only when dev is done
Verify Behavior Refactoring Clean code Better Quality
The entire team
As soon and often as possible
Smaller… As needed …Larger
Mock anything as needed
Mostly Fake data
High
Slower
Should be made easy
Preferably before (ATDD)
40. Test automation is your concern!
Quality comes from the code and the design
Design should evolve over time. Test automation enable that
Collaborate with the testers and test automation developers
Most principles apply to all test scopes
Why I was so interested in Test Automation
Test Automation is not (just) about testing, and that’s why it’s your concern!
Quality and Testing are 2 different things
Testers don’t control quality!
Developers do!
Test Automation is a tool that helps improve quality, if used correctly!
And what’s that “integration tests” even mean?!
this is dichotomic. I suggest a different paradigm I call “Test Scope”
But before I
באופן פשטני ודומה, בדיקות אוטומטיות הן תוכנה שמזינה קלט מסויים לתוך המערכת הנבדקת, בוחנת את הפלט ומדווחת אם הפלט מתאים לתוצאה הצפויה או לא.
באופן עקרוני, הפלט של כל מערכת (והמערכת הנבדקת בפרט) תלוי אך ורק בקלט שלה! בהנתן שזה המצב, אין כל סיבה שבדיקה אוטומטית לא תתן גם היא תמיד את אותה תוצאה עבור כל עוד המערכת הנבדקת לא השתנתה.
הבעיה היא שבפועל, רוב המערכות לא נראות כ"כ פשוטות, אלא נראות יותר כמו משהו כזה:...
למעשה יש לנו כאן אוסף של מערכות שכל אחת מהן מקבלת קלט ממספר מקורות, כולל:
§ תתי מערכות אחרות
§ מערכות חיצוניות
§ בסיסי נתונים
§ מידע מחיישנים שונים
תאריך ושעה... כולל שעון התזמון של מערכת ההפעלה שמשפיע על תזמון של thread-ים...
שאלה: מי פה כותב את הבדיקות האוטומטיות על סמך תסריטים שבודקים ידניים מגדירים? (מי מגדיר בעצמו?)
מה הבעיה עם זה?
□ לבודקים ידניים פחות חשוב העניין של יציבות כי הם יכולים להפעיל שיקול דעת ולהבין אם התוצאה שהם קיבלו שונה מהתוצאה הצפויה בגלל באג או בגלל שאיזשהו "קלט" שהם לא שולטים בו לא היה בדיוק מה שתוכנן.
□ בגלל זה בודקים ידניים הרבה פעמים גם לא טורחים להגדיר במדוייק את התוצאה הצפויה, אלא שוב, מסתמכים על השיקול דעת שלהם בזמן הרצת הבדיקה
□ לעתים קרובות לבודקים הידניים אין את היכולת לשלוט בקלט שמגיע ממקורות שונים מלבד ממשק המשתמש (ולעתים ה-database) ו/או לבדוק את הפלט שנשלח למקורות אחרים מלבד ה-UI
לעומת זאת, באוטומציה, חשוב שנהיה מסוגלים לשלוט בכל מקור קלט שיכול להשפיע על תוצאות הבדיקה! כמו כן, רצוי מאד שנהיה מסוגלים לבחון יעדי פלט אחרים מלבד ה-UI, בעיקר אם זאת המהות של המערכת...
§ למעשה, אנחנו צריכים "לסמן מסגרת" מסביב לרכיבים שאנחנו רוצים לבדוק, ולזהות את כל מקורות הקלט שיכולים להשפיע על הפלט שאותו אנחנו רוצים לבדוק <תמונה>
הערה: אם אנחנו יכולים להבטיח במידה מספיק גבוהה של אמינות שקלט מסויים לא יכול להשפיע על הפלט הנבדק, אז אנחנו לא חייבים לשלוט בו.
לשנות צבע של המילה ולמרכז
Don’t be stuck on the 3 types of tests…
For functional tests, humans are better than machines in finding bugs
Bad abstractions, wrong encapsulation, duplications, etc. can lead to bugs
What causes it?
What can we do about it?
We must have a proper test automation suite to allow safe refactoring
Attributes of simple design:
Loosely-coupled
No duplication
Modular
Simple design requires less and simpler tests
This also applies to unit tests!
Unit tests may interfere with refactoring…
Either write E2E first or refactor
Top->Down
ביזנס
קצר וממוקד
(After slide: )
But how do we decide what to test? My best experience developing software was in a team that used the ATDD methodology:
It’s not always appropriate
Generally, good structure will lead to it.