Чи слід перевірити приватні методи чи лише публічні? [зачинено]


348

Я прочитав цю публікацію про тестування приватних методів. Зазвичай я їх не тестую, бо завжди думав, що швидше тестувати лише публічні методи, які будуть викликані ззовні об'єкта. Ви перевіряєте приватні методи? Чи повинен я завжди тестувати їх?



"Чи варто перевірити приватних помічників?" Так. "Чи слід тестувати приватних помічників безпосередньо?" Зазвичай це залежить, якщо ви можете легко протестувати їх через загальнодоступний інтерфейс, навіщо тестувати їх безпосередньо? Якщо стає складним для перевірки всіх аспектів помічників за допомогою загальнодоступного інтерфейсу, то чи компонент пережив своє існування як єдине ціле?
Михай Даніла

Відповіді:


328

Я не підключаю тестові приватні методи. Приватний метод - це деталь реалізації, який слід приховати користувачам класу. Тестування приватних методів порушує інкапсуляцію.

Якщо я виявив, що приватний метод є величезним або складним або достатньо важливим, щоб вимагати власних тестів, я просто перекладаю його в інший клас і оприлюднюю його там ( метод Object ). Тоді я можу легко перевірити раніше приватний, але тепер публічний метод, який зараз живе на власному класі.


88
Я не погоджуюсь. В ідеалі ви пишете швидкий тест, перш ніж розпочати кодування функції. Подумайте про типовий вхід та про те, яким буде вихід. Напишіть тест (який не повинен займати у вас більше декількох секунд) і введіть код, поки він не отримає правильний тест. Немає підстав відмовлятися від цього стилю роботи для приватних методів.
Френк

254
Сказати, що приватні методи не потребують тестування - це як сказати, що автомобіль добре, якщо він добре працює, і не має значення, що знаходиться під капотом. Але чи не було б приємно знати, що якийсь кабель всередині починає розшаровуватися - навіть якщо користувач нічого не помічає? Звичайно, ви можете зробити все загальнодоступним, але який сенс? Ви завжди хочете отримати деякі приватні методи.
Френк

37
"Приватний метод - це деталізація реалізації, яку слід приховати користувачам класу." але чи справді тести на тій же стороні інтерфейсу класу, що і "звичайні" (під час виконання) користувачі? ;)
mlvljr

34
Небезпека витягнути все, що ви хочете перевірити, в інший клас полягає в тому, що ви можете закінчити надмірні інженерні роботи свого продукту і мати мільйон багаторазових компонентів, які ніколи не використовуються повторно.
окулус

44
Порівнювати фрагмент коду з автомобілем - неправильно; код не « погано йде » з часом, він вічний . Якщо ваше тестування загальнодоступного інтерфейсу доходить лише до того, щоб визначити, що він " добре виглядає ", то тестування публічного коду недостатньо. У цьому випадку тестування приватних методів окремо не зробить загальний тест завершеним незалежно від того, наскільки ви намагаєтесь. Сконцентруйтеся на вичерпному тестуванні свого загальнодоступного коду в цілому, використовуючи знання внутрішніх функцій коду для створення правильних сценаріїв.
іржа

293

Яка мета тестування?

Більшість відповідей поки що говорять про те, що приватні методи - це деталі впровадження, які не мають значення (або, принаймні, не мають значення), поки публічний інтерфейс добре перевірений і працює. Це абсолютно правильно, якщо ваша єдина мета тестування - гарантувати, що відкритий інтерфейс працює .

Особисто моє основне використання для тестів коду - це гарантувати, що майбутні зміни коду не спричинятимуть проблем, а також допомагати моїм зусиллям налагодження, якщо вони є. Я вважаю, що тестування приватних методів так само ретельно, як і публічний інтерфейс (якщо не більше!) Сприяє цій меті.

Поміркуйте: у вас є публічний метод A, який викликає приватний метод B. A і B обидва використовують метод C. Змінено C (можливо, ви, можливо, постачальник), що призведе до того, що A починає провалювати свої тести. Чи не було б корисним також тести на B, навіть якщо він приватний, так що ви знаєте, чи проблема полягає у використанні А в C, у використанні B в C або в обох?

Тестування приватних методів також додає значення у випадках, коли покриття тесту публічним інтерфейсом є неповним. Хоча в цілому ми хочемо уникати такої ситуації, тестування блоку ефективності залежить як від тестів, що знаходять помилки, так і пов'язаних з цим витрат на розробку та обслуговування цих тестів. У деяких випадках переваги 100% тестового покриття можуть бути оцінені недостатніми, щоб гарантувати витрати на ці випробування, створюючи прогалини в покритті тесту на публічному інтерфейсі. У таких випадках добре націлений тест приватного методу може бути дуже ефективним доповненням до кодової бази.


72
Проблема тут полягає в тому, що ті "майбутні зміни коду" незмінно означають рефакторинг внутрішньої роботи деякого класу. Це трапляється так часто, що написання тестів створює перешкоду для рефакторингу.
Програматор поза законом

40
Крім того, якщо ви постійно змінюєте свої тести на одиницю, то ви втратили всю послідовність у тестуванні і навіть потенційно зможете створювати помилки в одиничних тестах.
17 з 26

6
@ 17 Якщо тести та реалізація будуть змінені синхронно (як, здається, так і повинно бути), проблем буде набагато менше.
mlvljr

11
@Sauronlord, причина тестування приватних методів полягає в тому, що якщо ви протестуєте лише загальнодоступні методи, коли тестtestDoSomething()testDoSomethingPrivate() виявляється невдалим, ми не знаємо безпосередньо, де першопричина відмови. Це може бути або в одному, або . Це робить тест менш цінним. . Ось кілька причин для тестування особистого stackoverflow.com/questions/34571 / ... :
Pacerier

3
@Pacerier Існує також різниця між тестуванням вашого коду та постійним автоматизованим тестовим процесом. Очевидно, ви повинні переконатися, що ваш приватний метод працює, але у вас не повинно бути тестів, що з'єднують вас із приватним методом, оскільки це не є частиною випадку використання програмного забезпечення.
Дідьє А.

150

Я схильний дотримуватися порад Дейва Томаса та Енді Ханта у книзі « Тестування прагматичних одиниць» :

Взагалі, ви не хочете порушувати жодну інкапсуляцію заради тестування (або, як мама казала, "не виставляйте своїх приватних осіб!"). Більшу частину часу вам слід мати можливість протестувати клас, застосовуючи його публічні методи. Якщо є значна функціональність, яка прихована за приватним або захищеним доступом, це може бути попереджувальним знаком того, що там є інший клас, який бореться за вихід.

Але іноді я не можу зупинити себе на тестуванні приватних методів, тому що це дає мені впевненість у тому, що я будую повністю надійну програму.


9
Я рекомендую вимкнути одиничні тести, націлені на приватні методи. Вони є кодовим з'єднанням і обтяжуватимуть майбутні роботи по рефакторингу або навіть іноді заважають додавати чи змінювати функції. Корисно написати тест для них, коли ви їх реалізуєте, як автоматизований спосіб стверджувати, що ви працюєте з впровадження, але це не вигідно зберігати тести як регресію.
Дідьє А.

61

Я відчуваю вимушеність перевіряти приватні функції, оскільки я все більше і більше дотримуюся однієї з наших останніх рекомендацій із забезпечення якості в нашому проекті:

Не більше 10 в цикломатичній складності на функцію.

Тепер побічним ефектом застосування цієї політики є те, що багато моїх дуже великих публічних функцій поділяються на багато більш цілеспрямованих, краще названих приватних функцій.
Загальнодоступна функція все ще існує (звичайно), але по суті зводиться до всіх цих приватних "підфункцій"

Це насправді круто, тому що зараз callstack набагато простіше читати (замість помилки у великій функції, у мене є помилка в підфункції з іменем попередніх функцій у callstack, щоб допомогти мені зрозуміти "як я туди потрапив")

Тим НЕ менше, тепер , здається , простіше блок-тест безпосередньо ці приватні функції, і залишити тестування великої суспільної функції свого роду тест «інтеграція» , де а потреба сценарію повинні бути розглянута.

Всього мої 2 копійки.


2
щоб реагувати на @jop, я не відчуваю потреби експортувати ці приватні функції (створені через поділ великої занадто цикломатичної складної публічної функції) в інший клас. Мені подобається, щоб вони все ще були щільно поєднані з громадською функцією, в тому ж класі. Але все-таки перевірена одиницею.
VonC

2
Мій досвід полягає в тому, що ці приватні методи - це просто корисні методи, які використовуються цими публічними методами. Іноді зручніше розділити початковий клас на два (або три) більш згуртовані класи, зробивши ці приватні методи загальнодоступними у власних класах, а отже, перевірити.
jop

7
ні, в моєму випадку ці нові приватні функції дійсно є частиною більшого алгоритму, представленого публічною функцією. Ця функція розділена на менші частини, які не є корисними, а є кроками більшого процесу. Звідси необхідність тестувати їх одиницею (а не
опробовувати цілий альго

Для тих , хто зацікавлений в цикломатическая складності, я додав питання по темі: stackoverflow.com/questions/105852 / ...
VonC

На жаль, URL-адресу питання змінили через помилку в заголовку! stackoverflow.com/questions/105852 / ...
VonC

51

Так, я перевіряю приватні функції, оскільки, хоча вони перевірені вашими загальнодоступними методами, в TDD (Test Driven Design) добре перевірити найменшу частину програми. Але приватні функції недоступні, коли ви перебуваєте в класі свого тестового блоку. Ось що ми робимо для перевірки наших приватних методів.

Чому у нас є приватні методи?

Приватні функції в основному існують у нашому класі, оскільки ми хочемо створити читабельний код у наших публічних методах. Ми не хочемо, щоб користувач цього класу називав ці методи безпосередньо, але через наші загальнодоступні методи. Також ми не хочемо змінювати їх поведінку під час розширення класу (у випадку захищеного), отже, це приватне.

Коли ми кодуємо, ми використовуємо тестово-керований дизайн (TDD). Це означає, що іноді ми натрапляємо на приватний функціонал і хочемо перевірити. Приватні функції не перевіряються в phpUnit, тому що ми не можемо отримати доступ до них у класі Test (вони є приватними).

Ми думаємо, що ось три рішення:

1. Ви можете протестувати своїх приватних осіб за допомогою своїх публічних методів

Переваги

  • Тестування прямого блоку (не потрібні «хаки»)

Недоліки

  • Програмісту необхідно розуміти публічний метод, тоді як він хоче лише перевірити приватний метод
  • Ви не тестуєте найменшу тестовану частину програми

2. Якщо приватне є таким важливим, то, можливо, саме кодовий код створити для нього новий окремий клас

Переваги

  • Ви можете перефактурувати це на новий клас, тому що якщо це важливо, його можуть знадобитися і інші класи
  • Тестова одиниця тепер є загальнодоступним методом, настільки перевіряється

Недоліки

  • Ви не хочете створювати клас, якщо він не потрібен, а використовується лише класом, з якого походить метод
  • Потенційні втрати продуктивності через додаткові накладні витрати

3. Змініть модифікатор доступу на (остаточний) захищений

Переваги

  • Ви протестуєте найменшу тестовану частину програми. При використанні остаточного захищеного функції функція не буде перезаписуваною (як і приватна)
  • Без втрати продуктивності
  • Без зайвих накладних витрат

Недоліки

  • Ви змінюєте приватний доступ до захищеного, це означає, що його доступні діти
  • Для його використання вам все ще потрібен клас Mock у вашому тестовому класі

Приклад

class Detective {
  public function investigate() {}
  private function sleepWithSuspect($suspect) {}
}
Altered version:
class Detective {
  public function investigate() {}
  final protected function sleepWithSuspect($suspect) {}
}
In Test class:
class Mock_Detective extends Detective {

  public test_sleepWithSuspect($suspect) 
  {
    //this is now accessible, but still not overridable!
    $this->sleepWithSuspect($suspect);
  }
}

Тож наш тестовий блок тепер може викликати test_sleepWithSuspect для перевірки нашої колишньої приватної функції.


eddy147, мені дуже подобається концепція тестування захищених методів через макети. Дякую!!!!
Теодор Р. Сміт

15
Я просто хочу зазначити, що в оригінальному описі TDD, в одиничному тестуванні, одиниця - це клас , а не метод / функція. Тож, коли ви згадуєте про "тестування найменшої частини програми", неправильно називати найменшу тестовану частину як метод. Якщо ви використовуєте цю логіку, ви можете також говорити один рядок коду замість цілого блоку коду.
Метт Квіглі

@Matt Одиниця роботи може вказувати на клас, але також на єдиний метод.
eddy147

4
@ eddy147 Тестування одиниць поставляється Test Driven Development, де одиниця була визначена як клас. Як це трапляється з «Інтернетом», семантика розширилася і означає цілу багато речей (тобто запитайте у двох людей, яка різниця між тестуванням одиниці та інтеграції, і ви отримаєте 7 відповідей). TDD мався на увазі як спосіб написання програмного забезпечення з принципами SOLID, включаючи одиночну відповідальність, коли клас несе єдину відповідальність і не повинен мати високої циклічної складності. Приватні методи, капсульовані, не мають відповідного одиничного тесту.
Метт Квіглі

"Коли ми кодуємо, ми використовуємо тестовий дизайн (TDD). Це означає, що іноді ми стикаємося з функцією, яка є приватною і хочемо протестувати." Я категорично не згоден з цим твердженням, будь ласка, дивіться мою відповідь нижче для отримання більш детальної інформації. TDD не означає, що ви змушені перевірити приватні методи. Ви можете випробувати тестування приватних методів: і це ваш вибір, але вас не робить TDD.
Метт Мессерсміт

41

Мені не подобається тестувати приватну функціональність з кількох причин. Вони наступні (це основні моменти для людей, які TLDR):

  1. Зазвичай, коли ви спокушаєтесь перевірити приватний метод класу, це запах дизайну.
  2. Ви можете протестувати їх через загальнодоступний інтерфейс (саме так ви хочете протестувати їх, оскільки саме так клієнт буде викликати / використовувати їх). Ви можете отримати помилкове почуття безпеки, побачивши зелене світло на всіх пройдених тестах для ваших приватних методів. Набагато краще / безпечніше перевірити кращі справи на ваших приватних функціях через ваш публічний інтерфейс.
  3. Ви ризикуєте серйозним дублюванням тестів (тести, які виглядають / відчувають себе дуже подібними), перевіряючи приватні методи. Це має великі наслідки, коли вимоги змінюються, оскільки буде порушено набагато більше тестів, ніж необхідно. Це також може поставити вас у становище, коли важко переробляти через ваш тестовий набір ... що є остаточною іронією, тому що тестовий набір є, щоб допомогти вам безпечно переробити та рефактор!

Я поясню кожне з них на конкретному прикладі. Виявляється, 2) і 3) дещо хитромудро пов'язані, тому їх приклад схожий, хоча я вважаю їх окремими причинами, чому не слід перевіряти приватні методи.

Існують випадки, коли тестування приватних методів є доцільним, важливо просто знати про перелічені вище недоліки. Пізніше я детальніше перейду над цим.

Я також зауважую, чому TDD не є вагомим приводом для тестування приватних методів у самому кінці.

Реконструюючи свій вихід із поганого дизайну

Один з найпоширеніших (анти) патернів, який я бачу, - це те, що Майкл Пірс називає класом "Айсберг" (якщо ви не знаєте, хто такий Майкл Пір'я, зайдіть, купіть / прочитайте його книгу "Ефективна робота зі спадщинним кодексом"). людина, про яку варто знати, якщо ви професійний інженер / розробник програмного забезпечення). Є й інші (анти) зразки, які спричиняють вирішення цієї проблеми, але це, безумовно, найпоширеніший, на який я натрапив. Класи «Айсберг» мають один публічний метод, а решта - приватні (саме тому перевірити приватні методи спокусливо). Його називають класом "Айсберг", оскільки зазвичай існує самотня публічна методика, але решта функціональності прихована під водою у вигляді приватних методів.

Оцінювач правил

Наприклад, ви можете перевірити GetNextToken(), подзвонивши по рядку послідовно і побачивши, що він повертає очікуваний результат. Така функція гарантує тест: така поведінка не є тривіальною, особливо якщо ваші правила токенізації складні. Давайте зробимо вигляд, що це не все так складно, і ми просто хочемо мотузки в жетонах, обмежених простором. Отже, ви пишете тест, можливо, це виглядає приблизно так (якийсь мовний агностичний псуедо-код, сподіваємось, ідея зрозуміла):

TEST_THAT(RuleEvaluator, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    re = RuleEvaluator(input_string);

    ASSERT re.GetNextToken() IS "1";
    ASSERT re.GetNextToken() IS "2";
    ASSERT re.GetNextToken() IS "test";
    ASSERT re.GetNextToken() IS "bar";
    ASSERT re.HasMoreTokens() IS FALSE;
}

Ну, це насправді виглядає досить приємно. Ми хотіли б переконатися, що ми підтримуємо цю поведінку під час внесення змін. Але GetNextToken()це приватна функція! Таким чином, ми не можемо перевірити його так, оскільки він навіть не збирається (припускаючи, що ми використовуємо мову, яка фактично застосовує публічну / приватну, на відміну від деяких мов скриптів, таких як Python). Але як щодо зміни RuleEvaluatorкласу на дотримання принципу єдиної відповідальності (єдиного принципу відповідальності)? Наприклад, у нас, здається, є аналізатор, токенізатор та оцінювач, застряглі в одному класі. Чи не було б краще просто розділити ці обов'язки? Крім того, якщо ви створюєте Tokenizerклас, то це публічні методи були б HasMoreTokens()і GetNextTokens(). У RuleEvaluatorкласі може бути аTokenizerоб’єкт як член. Тепер ми можемо зберегти той же тест, що і вище, за винятком того, що ми перевіряємо Tokenizerклас замість RuleEvaluatorкласу.

Ось як це може виглядати в UML:

Оцінювач правил відновлений

Зауважте, що цей новий дизайн збільшує модульність, тому ви могли потенційно повторно використовувати ці класи в інших частинах вашої системи (до цього ви не змогли приватні методи не використовувати повторно за визначенням). Це головна перевага розбиття оцінювача правил, а також підвищення зрозумілості / локальності.

Тест виглядав би надзвичайно схожим, за винятком того, що він би справді компілювався цього разу, оскільки GetNextToken()метод тепер відкритий для Tokenizerкласу:

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS FALSE;
}

Тестування приватних компонентів через загальнодоступний інтерфейс та уникнення дублювання тестів

Навіть якщо ви не думаєте, що можете розбити свою проблему на меншу кількість модульних компонентів (що ви можете 95% часу, якщо ви просто намагаєтесь це зробити), ви можете просто протестувати приватні функції через публічний інтерфейс. Багато разів приватні учасники не варто тестувати, оскільки вони будуть перевірені через загальнодоступний інтерфейс. Я багато разів бачу тести, які дуже схожі, але перевіряють дві різні функції / методи. У кінцевому підсумку відбувається те, що коли вимоги змінюються (і вони завжди є), тепер у вас є 2 розбиті тести замість 1. І якщо ви дійсно перевірили всі ваші приватні методи, у вас може бути більше, як 10 зламаних тестів замість 1. Коротше , тестування приватних функцій (за допомогоюFRIEND_TESTабо оприлюднення їх або використання рефлексії), яке в іншому випадку можна перевірити через загальнодоступний інтерфейс, може спричинити дублювання тесту . Ти справді цього не хочеш, тому що нічого не шкодить більше, ніж тестовий набір, що сповільнює тебе. Це має скоротити час розробки та зменшити витрати на обслуговування! Якщо ви протестуєте приватні методи, які в іншому випадку перевіряються через загальнодоступний інтерфейс, тестовий набір може зробити протилежне і активно збільшити витрати на обслуговування та збільшити час розробки. Коли ви робите приватну функцію загальнодоступною або використовуєте щось на кшталт FRIEND_TESTта / або відображення, зазвичай, в кінцевому рахунку, шкодуєте про це.

Розглянемо наступну можливу реалізацію Tokenizerкласу:

введіть тут опис зображення

Скажімо, SplitUpByDelimiter()відповідальність за повернення масиву таким чином, що кожен елемент масиву є маркером. Крім того, скажемо, що GetNextToken()це просто ітератор над цим вектором. Отже, ваш громадський тест може виглядати так:

TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);

    ASSERT tokenizer.GetNextToken() IS "1";
    ASSERT tokenizer.GetNextToken() IS "2";
    ASSERT tokenizer.GetNextToken() IS "test";
    ASSERT tokenizer.GetNextToken() IS "bar";
    ASSERT tokenizer.HasMoreTokens() IS false;
}

Давайте зробимо вигляд, що у нас є те, що Майкл Перо називає інструментом затискання . Це інструмент, який дозволяє торкатися приватних частин інших людей. Приклад - FRIEND_TESTз googletest або відображення, якщо мова підтримує його.

TEST_THAT(TokenizerTest, canGenerateSpaceDelimtedTokens)
{
    input_string = "1 2 test bar"
    tokenizer = Tokenizer(input_string);
    result_array = tokenizer.SplitUpByDelimiter(" ");

    ASSERT result.size() IS 4;
    ASSERT result[0] IS "1";
    ASSERT result[1] IS "2";
    ASSERT result[2] IS "test";
    ASSERT result[3] IS "bar";
}

Ну, скажімо, зараз вимоги змінюються, а токенізація стає набагато складнішою. Ви вирішили, що простого роздільника рядків не буде достатньо, і вам потрібен Delimiterклас, щоб впоратися з роботою. Природно, ви очікуєте, що один тест зламається, але біль посилюється при тестуванні приватних функцій.

Коли тестування приватних методів може бути доречним?

У програмному забезпеченні немає "одного розміру, який би відповідав усім". Іноді добре (і насправді ідеально) "порушувати правила". Я наполегливо рекомендую не перевіряти приватні функції, коли можете. Є дві основні ситуації, коли я думаю, що це нормально:

  1. Я широко працював із застарілими системами (саме тому я такий великий фанат Майкла Пір'я), і я сміливо можу сказати, що іноді просто безпечно просто перевірити приватну функціональність. Це може бути особливо корисно для отримання "тестів на характеристику" в базовий рівень.

  2. Ти поспішаєш і мусиш зробити найшвидше, що можливо, тут і зараз. Зрештою, ви не хочете перевіряти приватні методи. Але я скажу, що для вирішення проблем із дизайном зазвичай потрібен певний час на рефактор. І іноді доводиться відправляти через тиждень. Це нормально: робіть швидкі та брудні та випробовуйте приватні методи, використовуючи інструмент для обмацування, якщо це, на вашу думку, найшвидший і надійний спосіб виконати роботу. Але розумійте, що те, що ви зробили, було неоптимальним у довгостроковій перспективі, і, будь ласка, подумайте повернутися до нього (або, якщо про нього забули, але ви побачите це пізніше, виправте це).

Напевно, є й інші ситуації, коли це нормально. Якщо ви вважаєте, що це нормально, і у вас є хороше виправдання, тоді зробіть це. Ніхто вас не зупиняє. Просто будьте в курсі потенційних витрат.

Виправдання TDD

Як осторонь, я дуже не люблю людей, які використовують TDD як привід для тестування приватних методів. Я практикую TDD, і не думаю, що TDD змушує вас це робити. Ви можете спочатку написати свій тест (для вашого загальнодоступного інтерфейсу), а потім написати код, щоб задовольнити цей інтерфейс. Іноді я пишу тест для публічного інтерфейсу, і це задовольняю, записуючи також один-два менших приватних методу (але приватні методи я не перевіряю безпосередньо, але я знаю, що вони працюють, або мій публічний тест був би невдалим ). Якщо мені потрібно перевірити кращі випадки цього приватного методу, я напишу цілу купу тестів, які потраплять на них через мій публічний інтерфейс.Якщо ви не можете зрозуміти, як вдарити крайові корпуси, це сильний знак, що потрібно переробляти на невеликі компоненти, кожен з яких має свої власні загальнодоступні методи. Це знак, що приватні функції ви робите занадто багато, і виходять за рамки класу .

Крім того, іноді я знаходжу, що я пишу тест, який на даний момент занадто великий, щоб пережовувати, і тому я думаю, "так, я повернусь до цього тесту пізніше, коли в мене буде більше API для роботи" (я Я прокоментую це і зроблю це в моїй думці). Ось тут багато спільнот, з якими я зустрічався, потім почнуть писати тести на їхню приватну функціональність, використовуючи TDD як козла відпущення. Вони кажуть "о, ну, мені потрібен інший тест, але для того, щоб написати цей тест, мені знадобляться ці приватні методи. Тому, оскільки я не можу написати жоден виробничий код без написання тесту, мені потрібно написати тест для приватного методу ". Але те, що їм насправді потрібно робити, - це рефакторинг на більш дрібні та багаторазові компоненти, а не додавання / тестування ряду приватних методів до їх поточного класу.

Примітка:

Я відповів на подібне запитання щодо тестування приватних методів за допомогою GoogleTest трохи раніше. Я в основному змінив цю відповідь, щоб бути тут більш агностичним мовою.

PS Ось відповідна лекція про уроки айсберга та інструменти для шпигування Майкла Пера: https://www.youtube.com/watch?v=4cVZvoFGJTU


Проблема, яка виникає у мене з переліком "ви могли потенційно повторно використовувати ці класи в інших частинах вашої системи" як перевагу, полягає в тому, що іноді причина, яку я позначаю функцією, є приватною, тому що я не хочу, щоб її використовували інші частини система. Це специфічна для мови проблема: в ідеалі це буде приватним для "модуля", але якщо мова не підтримує це (наприклад, PHP), мій клас представляє модуль, а не одиницю: приватні методи є кодом для багаторазового використання з власними контрактами, але їх слід повторно використовувати лише в межах цього класу.
IMSoP

Я розумію, що ви говорите, але мені подобається, як спільнота Python вирішує це питання. Якщо ви називаєте "приватного" учасника, про який йде мова, ведучим _, він сигналізує "ей, це" приватний ". Ви можете використовувати його, але повне розкриття, воно не було розроблене для повторного використання, і ви повинні використовувати його лише в тому випадку, якщо ви справді знайте, що ви робите ». Ви можете скористатися однаковим підходом на будь-якій мові: оприлюднити цих членів, але позначити їх провідними _. Або, можливо, ці функції справді повинні бути приватними і просто перевірені через загальнодоступний інтерфейс (детальну інформацію див. У відповіді). Це від випадку до випадку, ніякого загального правила
Метт Мессерсміт

26

Я думаю, що найкраще просто перевірити публічний інтерфейс об'єкта. З точки зору зовнішнього світу, має значення лише поведінка загальнодоступного інтерфейсу, і саме до цього слід спрямовувати ваші одиничні тести.

Після того, як для об’єкта написано кілька твердих тестових одиниць, ви не хочете повертатися назад і змінювати ці тести лише тому, що змінилася реалізація інтерфейсу. У цій ситуації ви зіпсували послідовність тестування свого пристрою.


21

Якщо ваш приватний метод не перевіряється за допомогою виклику ваших публічних методів, то що це робить? Я говорю про приватну, не захищену чи другу.


3
Дякую. Це напрочуд недооцінений коментар і особливо все ще актуальний навіть через майже 8 років з часу його написання.
Sauronlord

1
З тими ж міркуваннями можна стверджувати лише тестування програмного забезпечення з користувальницького інтерфейсу (тестування на рівні системи), тому що якось кожна функція в програмному забезпеченні буде виконуватися якось звідти.
Дірк Геррманн

18

Якщо приватний метод є чітко визначеним (тобто він має функцію, яку можна перевірити і не має на меті змінюватись з часом), то так. Я перевіряю все тестувальне, де це має сенс.

Наприклад, бібліотека шифрування може приховати той факт, що вона виконує блокове шифрування за допомогою приватного методу, який шифрує одночасно лише 8 байт. Я б написав для цього тест на одиницю - це не призначено для зміни, навіть якщо він прихований, і якщо він справді зламається (наприклад, завдяки майбутнім підвищенням продуктивності), то я хочу знати, що ця приватна функція зламана, а не просто що одна з громадських функцій зламалася.

Це прискорює налагодження пізніше.

-Адам


1
У цьому випадку, чи не було б сенсу перенести цей приватний метод до іншого класу, а потім просто зробити його публічним чи публічним статичним?
Програматор поза законом,

+1 Якщо ви не перевірите свої функції приватного члена, і ваш тест публічного інтерфейсу не вдасться, все, що ви отримаєте, - це результат, еквівалентний тому, що щось порушено, не маючи уявлення, що це таке.
Олумід

12

Якщо ви розробляєте тестові методи (TDD), ви протестуєте свої приватні методи.



4
Неправда, ви перевіряєте свої загальнодоступні методи, і як тільки тести проходять, ви витягуєте код у своїх публічних методах у приватні методи, що перешкоджають кроку "очищення". Тестування приватних методів є поганою ідеєю imo, оскільки це робить зміну способу впровадження важче (а що, коли колись ти хочеш змінити те, як ти щось робиш, ти повинен мати змогу змінити його та запустити всі свої тести, і якщо твій новий спосіб зробити тест все правильно, вони повинні пройти, я б не хотів для цього змінювати всі мої приватні тести).
Тессеракт

1
@Tesseract, якби я міг би схвалити ваш коментар не раз. "... ви повинні мати змогу змінити його і запустити всі ваші тести, і якщо ваш новий спосіб зробити це правильно, вони повинні пройти", що є однією з головних переваг одиничних тестів. Вони дають вам змогу впевнено реагувати на рефактори. Ви можете повністю змінити внутрішню роботу свого класу і (не переписуючи всі ваші тестові одиниці) впевнені, що ви нічого не зламали, оскільки всі ваші (існуючі) одиничні тести (у вашому публічному інтерфейсі) все ще проходять.
Лі

Не погоджуйтесь, дивіться мою відповідь нижче
Метт Мессерсміт

11

Я не є експертом у цій галузі, але одиничне тестування повинно перевірити поведінку, а не реалізацію. Приватні методи суворо є частиною впровадження, тому IMHO не слід перевіряти.


Де потім тестується реалізація? Якщо деяка функціональність використовує кешування, то це деталізація реалізації та кешування не перевіряється?
Дірк Геррман

11

Ми перевіряємо приватні методи за допомогою висновку, під якими я маю на увазі, що ми шукаємо загальне покриття тестування класу щонайменше на 95%, але лише наші тести вимагають публічних чи внутрішніх методів. Щоб отримати покриття, нам потрібно робити декілька дзвінків до громадськості / внутрішніх служб, грунтуючись на різних сценаріях, які можуть виникати. Це робить наші тести більш уважними щодо мети коду, який вони тестують.

Відповідь Трампі на посаду, яку ви пов’язали, найкраща.


9

Одиничні тести, на мою думку, призначені для тестування публічних методів. Ваші публічні методи використовують ваші приватні методи, тому опосередковано вони також проходять перевірку.


7

Я певний час готувався над цим питанням, особливо, намагаючись в TDD.

Я зіткнувся з двома повідомленнями, які, на мою думку, вирішують цю проблему досить ретельно у випадку TDD.

  1. Тестування приватних методів, TDD та Тестово-рефакторинг
  2. Тестова розробка не тестує

Підсумок:

  • При використанні тестових методів розробки (проектування) приватні методи повинні виникати лише під час процесу повторного факторингу вже працюючого та перевіреного коду.

  • За своєю сутністю процесу будь-який фрагмент простої функції реалізації, витягнутий із ретельно перевіреної функції, буде самоперевірений (тобто покриття непрямим тестуванням).

Мені здається досить зрозумілим, що на початку частини кодування більшість методів будуть функціями вищого рівня, оскільки вони інкапсулюють / описують дизайн.

Тому ці методи будуть загальнодоступними і перевірити їх буде досить просто.

Приватні методи з’являться пізніше, коли все буде добре, і ми будемо переосмислені заради читабельності та чистоти .


6

Як цитується вище, "Якщо ви не протестуєте свої приватні методи, то як ви знаєте, що вони не порушаться?"

Це головне питання. Один з важливих моментів одиничних тестів - це знати, де, коли і як щось прорвалося якнайшвидше. Таким чином, зменшується значна кількість зусиль з розвитку та забезпечення якості. Якщо все, що тестується, є загальнодоступним, то ви не маєте чесного висвітлення та розмежування внутрішніх справ класу.

Я знайшов один з найкращих способів зробити це - просто додати тестову посилання на проект і поставити тести в клас, паралельний приватним методам. Введіть відповідну логіку побудови, щоб тести не вбудовувалися в кінцевий проект.

Тоді ви маєте всі переваги тестування цих методів, і ви можете виявити проблеми за секунди проти хвилин або годин.

Отже, підсумовуючи, так, одиничне тестування ваших приватних методів.


2
Я не погоджуюсь. "Якщо ви не протестуєте свої приватні методи, то як ви знаєте, що вони не зламаються?" : Я знаю це, тому що якщо мої приватні методи будуть порушені, то тести, які перевіряють мої публічні методи, які покладаються на ці приватні методи, не зможуть. Мені не хочеться міняти свої тести щоразу, коли я передумую, як реалізувати публічні методи. Я також думаю, що головний інтерес одиничних тестів полягає не в тому, щоб конкретно знати, який рядок коду є несправним, а він дозволяє бути більш-менш впевненим, що ви нічого не зламали під час внесення змін (до приватних методів).
Тессеракт

6

Ви не повинні . Якщо ваші приватні методи мають достатню складність, яку потрібно перевірити, слід перенести їх до іншого класу. Зберігайте високу згуртованість , клас повинен мати лише одне призначення. Загальнодоступного інтерфейсу класу має бути достатньо.


3

Якщо ви не перевіряєте свої приватні методи, як ви знаєте, що вони не порушаться?


19
Написавши тести ваших публічних методів.
підводне плавання

3
Ці приватні методи нібито називаються загальнодоступними методами класу. Тому просто протестуйте публічні методи, які називають приватні методи.
джойп

1
Якщо ваші публічні методи функціонують належним чином, очевидно, приватні методи, до яких вони отримують доступ, функціонують належним чином.
17 з 26

Якщо тести ваших загальнодоступних методів виходять з ладу, ви моментально знаєте, що на вашому об'єкті / компоненті / тощо щось не вірно.
Роб

3
Це дійсно добре, однак, знати , що це внутрішня функція , а не тільки зовнішні функції , які зламали (або , навпаки , що внутрішні функції добре , і ви можете зосередитися на зовнішньому).
Адам Девіс

2

Це, очевидно, залежить від мови. Раніше, використовуючи c ++, я оголосив клас тестування як клас друзів. На жаль, це вимагає, щоб ваш виробничий код знав про клас тестування.


5
Ключове слово друзів мене сумує.
Роб

Це не проблема, якщо тестовий клас реалізований в іншому проекті. Важливо те, що виробничий код не посилається на клас тестування.
Олумід

2

Я розумію точку зору, коли приватні методи розглядаються як деталі реалізації та їх не потрібно перевіряти. І я б дотримувався цього правила, якби нам довелося розвиватися лише поза об'єктом. Але ми, чи ми є якимись обмеженими розробниками, які розробляють лише поза об’єктами, називаючи лише їхні публічні методи? Або ми насправді також розробляємо цей об’єкт? Оскільки ми не зобов’язані програмувати зовнішні об'єкти, нам, ймовірно, доведеться залучати ці приватні методи до нових публічних, які ми розробляємо. Чи не було б чудово знати, що приватний метод протидіє всім шансам?

Я знаю, що деякі люди можуть відповісти, що якщо ми розробляємо інший публічний метод у цьому об'єкті, тоді цей метод повинен бути перевірений, і це все (приватний метод може продовжувати жити без тесту). Але це справедливо і для будь-яких публічних методів об’єкта: при розробці веб-програми всі публічні методи об’єкта викликаються з методів контролерів, і тому вони можуть розглядатися як деталі реалізації для контролерів.

То чому ми одиниці тестування об'єктів? Оскільки це справді важко, не можна сказати, неможливо бути впевненим, що ми тестуємо методи контролерів з відповідним входом, який запустить усі гілки базового коду. Іншими словами, чим вище ми в стеці, тим складніше перевірити всю поведінку. Так само і для приватних методів.

Для мене межа між приватним та публічним методами - це психологічний критерій, коли мова йде про тести. Критерії, які для мене важливіші:

  • метод називається не раз з різних місць?
  • метод досить складний, щоб вимагати тестів?

1

Якщо я виявив, що приватний метод є величезним або складним або достатньо важливим, щоб вимагати власних тестів, я просто перекладаю його в інший клас і оприлюднюю його там (метод Object). Тоді я можу легко перевірити раніше приватний, але тепер публічний метод, який зараз живе на власному класі.


1

Я ніколи не розумію поняття Unit Test, але тепер я знаю, яка це мета.

Тест на одиницю не є повним тестом . Отже, це не заміна QA та ручного тестування. Концепція TDD в цьому аспекті помилкова, оскільки ви не можете протестувати все, включаючи приватні методи, а також методи, що використовують ресурси (особливо ресурси, які ми не маємо під контролем). TDD базує всю свою якість - те, чого не вдалося досягти.

Тест одиниці - це більше тест повороту. Ви відзначаєте деякий довільний шар, і результат зсуву повинен залишатися однаковим.


1

Загальнодоступні та приватні не є корисною відмінністю для того, який apis потрібно викликати з ваших тестів, а також метод проти класу. Більшість тестових одиниць видно в одному контексті, але приховано в інших.

Важливо - покриття та витрати. Вам потрібно мінімізувати витрати при досягненні цілей покриття вашого проекту (лінія, галузь, шлях, блок, метод, клас, клас еквівалентності, тематика використання ... все, що вирішить команда).

Тому використовуйте інструменти, щоб забезпечити охоплення, і спроектуйте свої тести, щоб викликати найменші витрати (коротко- та довгострокові ).

Не робіть тести дорожче, ніж потрібно. Якщо це найдешевше, лише тестувати громадські точки входу, зробіть це. Якщо тестувати приватні методи найдешевше, зробіть це.

Коли ви будете більш досвідчені, вам стане краще прогнозувати, коли варто рефакторинг, щоб уникнути довгострокових витрат на тест-обслуговування.


0

Якщо метод досить значний / досить складний, зазвичай я зроблю його «захищеним» і протестую. Деякі методи залишатимуться приватними та неявно перевірятимуться як частина одиниць тестів для публічно захищених методів.


1
@VisibleForTesting - це примітка до цього. Я б не розслаблював інкапсуляцію для тестування, скоріше скористався dp4j.com
simpatico

0

Я бачу, що багато людей перебувають у тій же лінії мислення: тестування на громадському рівні. але хіба це не наша команда з QA? Вони перевіряють вхід і очікуваний вихід. Якщо ми, як розробники, перевіряємо лише публічні методи, то ми просто переробляємо завдання QA і не додаємо ніяких цінностей за допомогою «тестування одиниць».


Нинішня тенденція полягає в тому, щоб скоротити або не мати команди з якості. Ці модульні тести стають автоматизованими тестами, які виконуються кожного разу, коли інженер натискає код на головну гілку. Навіть із забезпеченням якості немає можливості перевірити всю програму так само швидко, як автоматизовані тести.
Патрік Дежардінс

0

Відповідь "Чи слід перевірити приватні методи?" є "....... іноді". Як правило, ви повинні тестувати інтерфейс своїх класів.

  • Однією з причин є те, що вам не потрібно подвійне покриття для функції.
  • Інша причина полягає в тому, що якщо ви зміните приватні методи, вам доведеться оновлювати кожен тест для них, навіть якщо інтерфейс вашого об’єкта зовсім не змінився.

Ось приклад:

class Thing
  def some_string
    one + two
  end

  private 

  def one
    'aaaa'
  end

  def two
    'bbbb'
  end

end


class RefactoredThing
def some_string
    one + one_a + two + two_b
  end

  private 

  def one
    'aa'
  end

  def one_a
    'aa'
  end

  def two
    'bb'
  end

  def two_b
    'bb'
  end
end

У RefactoredThingвас тепер є 5 тестів, 2 з яких ви повинні були оновити рефакторінга, але його функціональність об'єкта дійсно не змінилося. Тож скажімо, що речі складніші за це, і ви маєте певний метод, який визначає порядок виводу, наприклад:

def some_string_positioner
  if some case
  elsif other case
  elsif other case
  elsif other case
  else one more case
  end
end

Це не повинно бути запущено стороннім користувачем, але ваш інкапсуляційний клас може бути важким, щоб запускати таку логіку через нього знову і знову. У цьому випадку, можливо, ви скоріше вилучите це в окремий клас, надайте цьому класу інтерфейс і протестуйте його.

І нарешті, скажімо, що ваш головний об’єкт надмірно важкий, а метод зовсім маленький, і вам справді потрібно переконатися, що результат правильний. Ви думаєте: «Я повинен перевірити цей приватний метод!». У вас що, можливо, ви можете зробити ваш об'єкт легшим, передавши частину важкої роботи як параметр ініціалізації? Тоді ви можете пройти щось легше і протестувати проти цього.


0

Ні. Ви не повинні перевіряти приватні методи, чому? і більше того, що популярний фреймворк, такий як Mockito, не підтримує тестування приватних методів.


0

Один головний момент

Якщо ми перевіряємо правильність логіки, а приватний метод несе логіку, ми повинні перевірити її. Чи не так? То чому ми збираємось пропустити це?

Написання тестів, що базуються на наочності методів, абсолютно не має значення.

І навпаки

З іншого боку, головна проблема викликає приватний метод поза початковим класом. А також є обмеження щодо знущання над приватним методом у деяких знущальних інструментах. (Наприклад: Mockito )

Хоча є деякі засоби, такі як Power Mock, які це підтримують, це небезпечна операція. Причина полягає в тому, що для цього потрібно зламати СВМ.

Одна з проблем, яка може бути виконана (якщо ви хочете написати тестові випадки для приватних методів)

Оголосити ці приватні методи захищеними . Але це може бути не зручно для кількох ситуацій.


0

Йдеться не лише про державні чи приватні методи чи функції, це про деталі реалізації. Приватні функції - лише один аспект деталей реалізації.

Зрештою, тестування одиниць - це підхід до тестування білого поля. Наприклад, той, хто використовує аналіз покриття для виявлення частин коду, які були занедбані при тестуванні, переходить до деталей реалізації.

A) Так, вам слід протестувати деталі реалізації:

Подумайте про функцію сортування, яка з міркувань продуктивності використовує приватну реалізацію BubbleSort, якщо є до 10 елементів, і приватну реалізацію іншого підходу для сортування (скажімо, гипсорта), якщо є більше 10 елементів. Публічний API - це функція сортування. Однак ваш тестовий набір краще використовує знання про те, що насправді використовуються два алгоритми сортування.

У цьому прикладі, безумовно, ви могли б виконати тести на загальнодоступному API. Однак для цього потрібно мати ряд тестових випадків, які виконують функцію сортування з більш ніж 10 елементами, таким чином, щоб алгоритм згруповання був досить добре перевірений. Існування лише таких тестових випадків є свідченням того, що тестовий набір підключений до деталей реалізації функції.

Якщо відомості про реалізацію функції сортування змінюються, можливо, таким чином, що межа між двома алгоритмами сортування зміщується або ж замінюється сукупність на об'єднання або що завгодно: Існуючі тести продовжуватимуть працювати. Однак їх значення тоді сумнівне, і вони, ймовірно, повинні бути перероблені, щоб краще перевірити змінену функцію сортування. Іншими словами, будуть потрібні зусилля з обслуговування, незважаючи на те, що тести проходили на загальнодоступному API.

В) Як перевірити деталі реалізації

Однією з причин, чому багато людей стверджують, що не слід перевіряти приватні функції або деталі реалізації, є те, що більш детально змінити деталі реалізації. Ця більша ймовірність зміни хоча б є однією з причин приховування деталей реалізації за інтерфейсами.

Тепер припустимо, що реалізація за інтерфейсом містить більші приватні частини, для яких окремі тести на внутрішньому інтерфейсі можуть бути опцією. Деякі люди стверджують, що ці частини не слід перевіряти, коли вони приватні, їх слід перетворити на щось публічне. Після публічного, одиничного тестування цього коду було б добре.

Це цікаво: Хоча інтерфейс був внутрішнім, він, ймовірно, змінився, будучи деталлю реалізації. Беручи той самий інтерфейс, оприлюднюючи його, відбувається деяка магічна трансформація, а саме перетворення його в інтерфейс, який менш імовірно зміниться. Очевидно, є певна вада в цій аргументації.

Але за цим є деяка правда: під час тестування деталей реалізації, зокрема, з використанням внутрішніх інтерфейсів, слід прагнути використовувати інтерфейси, які, ймовірно, залишаються стабільними. Чи може бути якийсь інтерфейс стабільним, однак, не просто вирішується, виходячи з того, є державним чи приватним. У проектах зі світу, над якими я працюю певний час, публічні інтерфейси також досить часто змінюються, і багато приватних інтерфейсів залишаються недоторканими століттями.

І все-таки є правильним принципом використання "вхідних дверей спочатку" (див. Http://xunitpatterns.com/Principles%20of%20Test%20Automation.html ). Але майте на увазі, що це називається «вхідні двері спочатку», а не «лише вхідні двері».

В) Підсумок

Перевірте також деталі реалізації. Віддайте перевагу тестуванню на стабільних інтерфейсах (державних або приватних). Якщо відомості про впровадження змінюються, тести на загальнодоступному API повинні бути переглянуті. Перетворення чогось приватного в публічне не змінює магічної стабільності.


0

Так, ви повинні перевірити приватні методи, де це можливо. Чому? Щоб уникнути непотрібного вибуху в просторі стану тестових випадків, який у кінцевому підсумку просто неявно тестує ті ж приватні функції повторно на одних і тих же входах. Пояснимо, чому на прикладі.

Розглянемо наступний трохи надуманий приклад. Припустимо, ми хочемо відкрити публічно функцію, яка займає 3 цілих числа і повертає істину, якщо і лише тоді, коли ці 3 цілі числа є простими. Ми можемо реалізувати це так:

public bool allPrime(int a, int b, int c)
{
  return andAll(isPrime(a), isPrime(b), isPrime(c))
}

private bool andAll(bool... boolArray)
{
  foreach (bool b in boolArray)
  {
    if(b == false) return false;
  }
  return true;
}

private bool isPrime(int x){
  //Implementation to go here. Sorry if you were expecting a prime sieve.
}

Тепер, якби ми дотримувались суворого підходу, що слід перевіряти лише загальнодоступні функції, нам було б дозволено протестувати, allPrimeа не isPrimeабо andAll.

В якості тестера, ми могли б бути зацікавлені в п'ять можливостей для кожного аргументу: < 0, = 0, = 1, prime > 1, not prime > 1. Але якщо бути ретельним, ми також повинні побачити, як поєднується кожна комбінація аргументів. Тож це 5*5*5= 125 тестових випадків, нам потрібно було б ретельно перевірити цю функцію відповідно до наших інтуїцій.

З іншого боку, якби нам дозволили протестувати приватні функції, ми могли б покрити стільки ж ґрунту за допомогою меншої кількості тестових випадків. Нам знадобиться лише 5 тестових випадків, щоб перевірити isPrimeтой же рівень, що і попередня інтуїція. І за гіпотезою про малий обсяг, запропонованою Деніелом Джексоном, нам потрібно було б лише протестувати andAllфункцію до невеликої довжини, наприклад, 3 або 4. Що було б не більше 16 тестів. Так 21 тест загалом. Замість 125. Звичайно, ми, мабуть, хотіли б виконати кілька тестів allPrime, але ми не будемо так зобов’язані вичерпно висвітлити всі 125 комбінацій вхідних сценаріїв, про які ми говорили, що нас хвилювали. Всього кілька щасливих стежок.

Надуманий приклад, напевно, але це було необхідно для чіткої демонстрації. І модель поширюється на реальне програмне забезпечення. Приватні функції, як правило, будівельні блоки найнижчого рівня, і тому часто поєднуються разом, щоб отримати логіку вищого рівня. Значення на більш високих рівнях, у нас більше повторень матеріалів нижчого рівня завдяки різним комбінаціям.


По-перше, вам не доведеться тестувати такі комбінації з чистими функціями, як ви показали. Дзвінки isPrimeсправді незалежні, тому тестувати кожну комбінацію наосліп є досить безцільним. По-друге, маркування чистої функції під назвою isPrimeприватне порушує стільки правил дизайну, що я навіть не знаю, з чого почати. isPrimeдуже чітко має бути публічною функцією. Попри це, я розумію, що ви говорите, незалежно від цього надзвичайно бідного прикладу. Тим НЕ менше він побудований від передумову ви хочете зробити комбіноване тестування, коли в реальних системах програмного забезпечення це рідко хороша ідея.
Метт Мессерсміт

Метт. Так, приклад не є ідеальним. Я вам це надам. Але принцип повинен бути очевидним.
Colm Bhandal

Приміщення не зовсім те, що ви хочете зробити комбіноване тестування. Це вам доведеться, якби ви обмежили себе тестуванням лише публічних фрагментів головоломки. Бувають випадки, коли ви хочете зробити чисту функцію приватною, щоб дотримуватися правильних принципів інкапсуляції. І цю чисто приватну функцію могли використовувати громадські. У поєднанні, можливо, з іншими чистими приватними функціями. У такому випадку, дотримуючись догми, яку ви не будете перевіряти на приватну, ви змушені будете робити комбіноване тестування на публічну функцію, а не робити модульне тестування приватних компонентів.
Colm Bhandal

0

Ви також можете зробити свій метод пакет приватним, тобто за замовчуванням, і ви повинні мати змогу перевірити його, якщо не потрібно, щоб він був приватним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.