товарищ задал вопрос, на который я не нашёл ответа, можете помочь?
В общем, он джун-тестировщик, пишет юнит-тесты на плюсах, и мол надо кровь из жопы протестировать приватный метод клиентский, не изменяя исходный код. Какие best practices можете посоветовать в данном случае?
завести структуру friend tester
Best practice -- писать юнит-тесты для публичного интерфейса, а не для кишочков реализации
Увы, требования таковы)
А что если тестирование интерфейса это уже не юнит, а интеграционный тест? А кишки реализации - юнит
В общем сомнительно утверждение, кишки реализации вполне себе тестят
Ну так вынеси в отдельный класс. Этот класс может быть использован только тестами и первым классом, который имеет эту реализацию как private
Плодить классы - это тоже плохо:)
А то щас придём к мусору типа пимпла
Классы - это инструмент. Тебе нужны тесты процесса. Этот процесс пихай в класс. Потом этот класс используй в ~ public api wrapper
В итоге у пользователя твоя внутрянка торчит
// Can be used only by UsableInterface and tests struct Testable { int sum(int a, int b) { return a + b; } }; class UsableInterface { public: std::string func(std::string s) { // ... int c = t.sum(1, 2); // ... } private: Testable t; };
Какая разница если в ide x2 лишних сущностей
Тебе нужны тесты или нет? 🙃
https://t.me/ProCxx/584494
Да проще в заголовок залезть и написать внутрь объявления friend. Ещё есть какая-то магия, что если в классе естсь хотя бы один шаблонный метод, его можно легально хакнуть и вытаскивать всё private
в исходном вопросе было уточнение, что сорцы тестируемого класса трогать низя
https://stackoverflow.com/questions/12993219/access-private-member-using-template-trick http://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.html
Приватный метод не нужно тестировать. Если нужно, он должен быть публичным
Увы, требующие идут в жопу
Напиши публичный метод bool testInternals() И тестируй там что угодно
Всем кто там поставил дизлайки мне это смешно немножко но тем не менее я ещё раз говорю тестировать приватные методы во-первых бессмысленно они приватные они не предназначены для засвечивания наружу, во-вторых их нельзя тестировать потому что они не составляют интерфейс класса А класс - Это у нас прежде всего что? Инкапсуляция! А это значит что? Разделение мира на две части внутри класса и снаружи класса то что внутри класса находится тебя касаться никогда не должно. Итак, приватные методы и протектед, не предназначены для клиентов класса, не должны тестироваться, и не должны упоминаться вообще никак ни в каких тестах потому что они могут меняться, их поведение может меняться, и они вообще могут исчезнуть или добавиться новые какие-то аналогичные. Это нормально. А вот ненормальная фиксировать их сигнатуры, их наличие и их поведение тестами. При этом Если уж так нужно их тестировать то значит эти тесты должны находиться внутри класса, внутри класса надо сделать метод типа testSelf и вызывать его в ходе юниттестов таким образом автор класса сможет тестировать класс и при этом имеет возможность его изменять
А если ты меняешь спецификаторы доступа к членам класса с private на public, ты начинаешь тестировать другой класс а не тот который будет в конце концов использоваться
У gtest где-то в гайдлайне написано, что в идеале приватные методы не должны тестироваться, но если всё-таки придется, то надо делать friend для теста
TImestamp про private vs public. Та же идея относится и к тестированию. https://youtu.be/Z_8lV0nwsc4?t=3196 Short transcription: Public is a more practical approach for doing things. So if you're ever dealt with massive code bases or tried to deal with someone else's library, if it's gone private by default, but you as a programmer actually needed that private behavior, it's a pain in the ass to just try and get out. Because it's like: "Oh, how do we get this out. It's like..." - you can't. Unless you copy the headers and will modify them in place and then you've just done something hacky. So my personal view is that the public/private distinction is better suited at a package level not at a type level. Many things people use objects for or give the arguments for at least like encapsulation, those arguments apply better to the package level, so the library level, module or whatever you wanna call it. That is sometimes because people are used to using these languages with classes and they don't really have package systems to them at all. That's why they're used to it. They don't really know any alternatives. TL;DR: Private/Public - это про модульный / пакетный / библиотечный уровень. И лишь иногда про классы.
Обсуждают сегодня