125 საკითხავი

Code Smell 299 - როგორ გააუმჯობესოთ Overloaded Test Setups

მიერ Maximiliano Contieri7m2025/05/10
Read on Terminal Reader

Ძალიან გრძელი; Წაკითხვა

გაფართოებული კონფიგურაცია, რომელიც მხოლოდ ნაწილად გამოიყენება, თქვენი ტესტიებს უფრო კავშირი და უფრო რთულია.
featured image - Code Smell 299 - როგორ გააუმჯობესოთ Overloaded Test Setups
Maximiliano Contieri HackerNoon profile picture

როდესაც თქვენი ტესტი კონფიგურაცია უფრო დიდია, ვიდრე რეალური ტესტი

TL;DR: ფართო კონფიგურაცია, რომელიც მხოლოდ ნაწილად გამოიყენება, თქვენი ტესტები უფრო კავშირი და უფრო რთული გაიგოს.

TL;DR: ფართო კონფიგურაცია, რომელიც მხოლოდ ნაწილად გამოიყენება, თქვენი ტესტები უფრო კავშირი და უფრო რთული გაიგოს.

პრობლემები

  • კონტაქტი
  • ლამაზი
  • გადაღების დრო
  • შეტყობინება კონტაქტი
  • Hidden Test დამოკიდებულებები
  • რთული შენარჩუნება
  • Brittle ტესტი Suite
  • confusing დამოკიდებულებები
  • Slow Execution გაკეთება
  • კონფიდენციალურობა

გადაწყვეტილებები

  1. შექმნა Focused Setup Methods
  2. Test-specific მოწყობილობები
  3. შექმნა მინიმალური setups
  4. ქარხნის ტესტირების მეთოდები

️ ️ ️

https://hackernoon.com/improving-the-code-one-line-at-a-time

https://maximilianocontieri.com/refactoring-011-replace-comments-with-tests

კონტაქტი

როდესაც თქვენ დააწკაპუნეთ ტესტები, თქვენ შეიძლება შექმნათ დიდი setup მეთოდი, რომელიც იწყება სხვადასხვა ოფისები.


თუ მხოლოდ ერთი ტესტი იყენებს ყველა ეს ოფექტებს, ხოლო სხვა ტესტიები იყენებენ მხოლოდ მცირე ნომერი, თქვენ შექმნათ უარყოფითი overhead.


ეს პოპულარული პრობლემა მოხდება, როდესაც თქვენ ვფიქრობთ, რომ მომავალში ტესტები შეიძლება საჭირო იყოს ფართო setup, ან როდესაც თქვენ გაგრძელებთ დაამატოთ existing setup გარეშე შეფასება, რაც ნამდვილად საჭიროა.


ტესტიები უფრო რთულია, რადგან მათ შეიცავს უარყოფითი კონტაქტი, და უფრო slow to execute because you initialize objects that are not used.

Sample კოდი

არასწორი

public class TVSeriesTest {
  private MovieSeries theEthernaut;
  private List<Character> characters;
  private List<Episode> episodes;
  private User user;
  private UserPreferences preferences;
  private RatingSystem ratingSystem;
  private StreamingService streamingService;
  private List<Review> reviews;
  
  @BeforeEach
  public void setUp() {
    // Create a complex movie series with many characters
    characters = new ArrayList<>();
    characters.add(new Character("Juan Salvo", "Richard Darin"));
    characters.add(new Character("Helen", "Carla Peterson")); 
    characters.add(new Character("Favalli", "Cesar Troncoso")); 
    
    // Create episodes
    episodes = new ArrayList<>();
    episodes.add(
      new Episode("The Snow", 2025, 121));
    episodes.add(
      new Episode("The Hands Strikes Back", 2027, 124)); 
    
    // Create user with preferences
    preferences = new UserPreferences();
    preferences.setPreferredGenre("Science Fiction");
    preferences.setPreferredLanguage("English");
    preferences.setSubtitlesEnabled(true);
    user = new User("JohnDoe", "john@example.com", preferences);
    
    // Create rating system with reviews
    ratingSystem = new RatingSystem(10);
    reviews = new ArrayList<>();
    reviews.add(
      new Review(user, "The Snow", 9, "Classic!"));
    reviews.add(
      new Review(user, "The Hands Strikes Back", 10, "Best one!"));
    ratingSystem.addReviews(reviews);
    
    // Create streaming service
    streamingService = new StreamingService("Netflix");
    streamingService.addMovieSeries("The Eternaut");
    
    // Finally create the movie series with all components
    theEthernaut = 
      new TVSeries("The Ethernaut", characters, episodes);
    theEthernaut.setRatingSystem(ratingSystem);
    theEthernaut.setAvailableOn(streamingService);
    
    // This method is too long. That is another smell
  }
  
  @Test
  public void testTVSeriesRecommendation() {
    // This test uses almost everything from the setup
    RecommendationEngine engine = new RecommendationEngine();
    List<Episode> recommended =
      engine.recommendations(user, theEternaut);
    
    assertEquals(2, recommended.size());
    assertEquals("The Hands Strikes Back",
      recommended.get(0).title());
    // You are testing the recomendation Engine
    // This is not this object's responsibility
  }
  
  @Test
  public void testEpisodeCount() {
    // This test only needs the episodes count
    assertEquals(2, theEthernaut.episodes().size());
  }
  
  @Test
  public void testCharacterLookup() {
    // This test only needs the characters
    // And not the rest of the setup
    Character juan = theEternaut.findCharacterByName("Juan Salvo");
    assertNotNull(juan);
    assertEquals("Juan Salvo", juan.actor());
  }
}

public class TVSeriesTest {
  // No shared setup
  
  @Test
  public void testRecommendation() {
    // Create only what's needed for this specific test
    // And move this test with the behavior
    TVSeries theEternaut = createTheEternautSeries();
    User homer = createUserWithPreferences();
    addReviewsForUser(theEternaut, homer);
    
    RecommendationEngine engine = new RecommendationEngine();
    List<Episode> recommended =
      engine.recommendations(homer, theEternaut);
    
    assertEquals(2, recommended.size());
    assertEquals("The Hands Strikes Back", 
      recommended.get(0).title());
  }
  
  @Test
  public void testEpisodeCount() {
    // Only create what's needed - just the episodes
    TVSeries theEternaut = new TVSeries("The Ethernaut");
    theEternaut.addEpisode(
      new Episode("The Snow", 2025, 121));
    theEternaut.addEpisode(
      new Episode("The Hands Strikes Back", 2027, 124)); 
    
    assertEquals(2, theEternaut.episodes().size());
  }
  
  @Test
  public void testCharacterLookup() {
    // Only create what's needed - just the characters
    TVSeries theEternaut = new TVSeries("The Eternaut");
    theEternaut.addCharacter(
      new Character("Juan Salvo", "Richard Darin"));
    theEternaut.addCharacter(
      new Character("Helen", "Carla Peterson")); 
    
    Character juan = theEternaut.findCharacterByName("Juan Salvo");
    assertNotNull(juan);
    assertEquals("Richard Darin", juan.actor());
  }
  
  // Helper methods for specific test setup needs
  private TVSeries createTheEternautTVSeries() {
    TVSeries series = new TVSeries("The Eternaut");
    series.addEpisode(
      new Episode("The Snow", 2025, 121));
    series.addEpisode(
      new Episode("The Hands Strikes Back", 2027, 124)); 
    return series;
  }
  
  private User createUserWithPreferences() {
    UserPreferences preferences = new UserPreferences();
    preferences.setPreferredGenre("Science Fiction");
    preferences.setPreferredLanguage("English");
    return new User("JohnDoe", "john@example.com", preferences);
  }
  
  private void addReviewsForUser(TVSeries series, User user) {
    RatingSystem ratingSystem = new RatingSystem(10);
    ratingSystem.addReview(
      new Review(user, "The Snow", 9, "Classic!"));
    ratingSystem.addReview(
      new Review(user, "The Hands Strikes Back", 10, "Best one!"));
    series.setRatingSystem(ratingSystem);
  }
}

კონტაქტი

  • [x] ავტომატური

თქვენ შეგიძლიათ იპოვოთ ეს ხასიათი, შედარებით ის, რაც დააყენა კონფიგურაციის მეთოდები და ის, რაც გამოიყენება თითოეული ტესტი.


იხილეთ ტესტები, რომლებიც გამოიყენებენ ნაკლებად, ვიდრე 50% ინტიმალური ოპტიმიზებული ოპტიმიზაცია.


კოდი მოცულობის ინსტრუმენტები შეუძლიათ დაეხმაროს აღინიშნა არ გამოიყენებული setup ობიექტები, რათა აჩვენოს, რა ნაწილები setup არ გააკეთა გარკვეული ტესტიები.


თუ თქვენ იპოვებთ, რომ შეტყობინებები შეტყობინება სხვადასხვა კონტექსტებს შექმნათ, ეს არის ნათელი მიმოხილვა, რომ საჭიროა გამოცდილება სპეციფიკური კონტექსტი.

️ ️

  • ტესტირება

დონე

  • [x] მეშვეობით

რატომ არის მნიშვნელოვანია ️

თითოეული ტესტი უნდა იპოვოს კონკრეტული რეალურ სამყაროში სცენარეთა.


გაფართოებული კონფიგურაცია შეშფოთებს ამ სიზუსტით, რაც რთულია იხილოთ, რა ტესტირება და გაზრდის შეცდომების შესაძლებლობა.


ეს შეჩერებულიBijectionტესტიებს უფრო რთულია იმიტომ, რომ არ შეუძლიათ აირჩიოთ, რა მხატვრები კონფიგურაცია არის მნიშვნელოვანი ტესტი და რა არის მხოლოდ ხმაური.


როდესაც ტესტი არ გაქვთ, თქვენ გაქვთ უფრო დრო კვლევა დამოკიდებულებები, რომელიც შეიძლება არ იყოს დაკავშირებული არჩევა.


ტესტი უფრო რთულია, რადგან ცვლილებები გამოიყენება არ გამოიყენება ობიექტები შეიძლება ჯერ კიდევ შეუწყოს ტესტიები, თუ ეს ობიექტები მონაწილეობა setup პროცესში.

AI კოდი გენერატორები ხშირად შექმნათ ეს ხასიათი, როდესაც ისინი შექმნათ მთლიანად ტესტირების მოწყობილობები, რომლებიც ცდილობენ ყველა შესაძლებელი სცენარეთა მოპოვებას.


ისინი უპირატესობას უპირატესობას fokus, რომელიც ეფუძნება დატვირთული setup მეთოდები, რომელიც დაინსტალირებს უფრო მეტი მოვლენები, ვიდრე საჭიროა თითოეული ტესტი.

კონტაქტი

AI შეუძლია იპოვოს ეს ხასიათი მარტივი ინსტრუქციებით, როგორიცაა "Optimize my test setup only to include what is needed for each test".


თანამედროვე AI ინსტრუმენტები შეუძლიათ შედარებით setup კოდი შედარებით ტესტი მეთოდის გამოყენება და გთავაზობთ მიზნით refactorings, დაშორებით გაზიარება setup და ტესტი კონკრეტული setup.

ცდილობენ მათ!

გაითვალისწინეთ: AI Assistants გააკეთა ბევრი შეცდომები

Suggested Prompt: Break ტესტები და setup

Suggested Prompt: Break ტესტები და setup

Without Proper Instructions

With Specific Instructions

ChatGPT

ChatGPT

Claude

Claude

Perplexity

Perplexity

Copilot

Copilot

Gemini

Gemini

DeepSeek

DeepSeek

Meta AI

Meta AI

Grok

Grok

Qwen

Qwen

ჩატი

ჩატი

კოლადის

კოლადის

შეშფოთება

შეშფოთება

Copilot

Copilot

ორმაგი

ორმაგი

DeepSeek

DeepSeek

მიზნები

მიზნები

გროკები

გროკები

კუნძული

კუნძული

კონტაქტი

Overloaded ტესტი კონფიგურაცია, რომელიც ინტიმურიზებს ოფექტები საჭირო მხოლოდ რამდენიმე ტესტი გააკეთოს თქვენი ტესტი კომპლექტი უფრო რთული გაიგოთ და შენარჩუნება.

როდესაც თქვენ შექმნათ ფუნქციონირებული კონფიგურაცია, რომელიც შეიცავს მხოლოდ ის, რაც თითოეული ტესტი საჭიროა, თქვენ გააუმჯობესებთ ტესტიების სიზუსტე, სიჩქარე და საიმედოობა.

შეამოწმეთ, რომ ტესტები მიზნადა დოკუმენტოს ქცევა მაგალითებით დაშეცვალოს კომენტარები.


ძალიან ბევრი უარყოფითი კონტაქტი იძლევა ეს მაგალითები ნაკლებად იხილონ. სუფთა ტესტები ვთქვა ნათელი ისტორია გარეშე უარყოფითი distractions.

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxiii

https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xli

მეტი ინფორმაცია

Disclaimer

Code Smells არის ჩემიკომენტარები.

კრედიტი

ფოტომარკინი SimonidesესUnsplash საწყისი


თუ თქვენ უნდა შექმნათ ბევრი სტრუქტურა, სანამ ტესტი, ალბათ თქვენ ტესტირება ძალიან ბევრი ფართობი

თუ თქვენ უნდა შექმნათ ბევრი სტრუქტურა, სანამ ტესტი, ალბათ თქვენ ტესტირება ძალიან ბევრი ფართობი

იმიჯი Shore


ეს სტატია არის ნაწილი CodeSmell სერია.


L O A D I N G
. . . comments & more!

About Author

Maximiliano Contieri HackerNoon profile picture
Maximiliano Contieri@mcsee
I’m a sr software engineer specialized in Clean Code, Design and TDD Book "Clean Code Cookbook" 500+ articles written

დაკიდეთ ტეგები

ეს სტატია იყო წარმოდგენილი...

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks