gtag('config', 'G-0PFHD683JR');
Price Prediction

Code Smell 299 – How to fix excess test settings

When the test setting is greater than the actual test

TL; DR: The enlarged preparation that is used in part only makes your tests more associated and difficult to understand.

Problems 😔

  • coupling
  • Reading ability
  • Lost implementation time
  • The context of misleading preparation
  • Hidden test consequences
  • The most difficult maintenance
  • Fragile test suite
  • Connective dependencies
  • The slower implementation
  • Misleading context

Solutions 😃

  1. Creating focused preparation methods
  2. Apply the matches for the test
  3. Create a minimum settings
  4. Implementing the methods of the test factory

Refactorings ⚙

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

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

Context 💬

When you write tests, you can create a large preparation method for creating different objects.

If only one test uses all these objects while other tests use a small sub -group, you create unnecessary public expenditures.

This common problem occurs when you expect future tests that you need an intense preparation, or when you continue to add an existing setting without evaluating what is really required.

It is difficult to understand the tests because they contain an unrelated context, and slower in implementation because you are creating objects that have not been used.

Code 📖

Error ❌

public class TVSeriesTest {
  private MovieSeries theEthernaut;
  private List characters;
  private List episodes;
  private User user;
  private UserPreferences preferences;
  private RatingSystem ratingSystem;
  private StreamingService streamingService;
  private List 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", "[email protected]", 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 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());
  }
}

Right 👉

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 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", "[email protected]", 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);
  }
}

Detection 🔍

You can discover this smell by comparing what was prepared in the preparation methods for what is used in each test.

Look for tests that use less than 50 % of the created objects.

Code coverage tools can help identify unused settings by showing parts of the setup that are not performed by certain tests.

If you find yourself writing a condition in preparing to create different contexts, this is a clear sign that needs to be prepared for the test instead.

Level 🔋

Why the objection is important 🗺

Each scenario test in the real world should reflect.

The enlarged settings break this clarity, which makes it difficult to see what is tested and increase the chance of errors.

This broken interception makes the tests more difficult to understand because you cannot determine the setting aspects of the preparation is crucial to testing and any noise.

When the test fails, you will spend more time investigating the dependencies that may not be related to failure.

The test becomes more fragile as changes on unused creatures still can break the tests if these organisms participate in the preparation process.

Amnesty International Generation 🤖

The artificial intelligence code generators often create this smell when comprehensive test equipment is created trying to cover all possible scenarios.

It gives priority to completion of focus, which leads to enlarged preparation methods that create more than individual tests.

Discover artificial intelligence 🥃

Amnesty International can discover this smell with simple instructions such as “improving my test setting only to include what is required for each test.”

Modern artificial intelligence tools can compare the setup code against the use of the test method, suggest targeted expulsion processes, and separate the joint setting from the testing for the test.

Try them! 🛠

Remember: Artificial Intelligence Assistants make many mistakes

A proposal wave: breaking the tests and preparation

Conclusion 🏁

Excess test settings that create objects that only some tests need make it difficult to understand your test set.

When you create focused settings that only contain what each test needs, you can improve your tests and reliability of your tests.

Remember that the tests aim to document behavior through examples and replace the comments.

Much of the context is not relevant makes these examples less readable. Clean tests tell a clear story without unnecessary deviations.

Relationships 👩‍❤

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

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

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

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

More information 📕

Leave responsibility 📘

The smell of the code is my opinion.

Credit 🙏

Photo by Marimine Simonides on non -earthquakes


If you have to create a lot of the structure before the test, you may experience it through many layers

James Shore


This article is part of the Codesmell series.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button