В своей практике с алгоритмами я обычно пишу код в собственном редакторе, а не во встроенных редакторах LeetCode и AlgoExpert, просто потому что мне нравится возможность сохранять множество различных решений, иметь универсальное хранилище всех проблем, которые я я работал, и потому что мне нравится возможность создавать определенные функции и тестировать сам. Говоря о тестировании, я хотел заняться этим какое-то время, и я решил начать сейчас, потому что только на днях я вырос, и мне достаточно комментировать и раскомментировать свои тесты. Пора мне поработать над автоматизацией моего тестирования, и, если честно, я почти не разбирался в том, как это «предполагается» делать, прежде чем писать этот пост, так что это будет своего рода совместное исследование.
Я покажу вам, над чем я работаю в настоящее время, кратко объясню проблему и решение, а затем разработаю способ автоматизации моих тестов, чтобы мне не приходилось вручную администрировать каждый тест индивидуально.
Приступим.

Здесь у нас есть алгоритм, который принимает на вход массив упорядоченных целых чисел и выводит упорядоченный массив целых чисел, где каждое значение на входе представлено этим значением в квадрате на выходе.
Каждое значение во входном массиве является целым числом, как упоминалось ранее, но не каждое число является положительным. Когда отрицательное число возводится в квадрат, оно становится положительным, и значение этого для нас состоит в том, что, когда мы работаем с входным массивом, содержащим отрицательные числа, нам придется отсортировать получившийся квадратный массив, прежде чем возвращать его в качестве вывода.

На самом деле это решение состоит всего из двух частей:

  1. Прокрутите входной массив, умножая значение каждого индекса на себя, Math.pow (‹your_value›, multiple), и вставьте это новое значение в переменную, чтобы сохранить массив новых значений. , newArr.
  2. Эта последняя часть, строка 34, обрабатывает случай, когда мы работаем с отрицательными числами. Поскольку метод sort () увеличивает сложность нашего решения, мы хотим использовать его только тогда, когда он нам нужен, то есть когда у нас есть отрицательное число во входных данных. И наш ввод упорядочен, поэтому мы можем просто проверить, является ли значение в первом индексе нашего входного массива отрицательным, if (array [0] ‹1), и если это так, то мы сортируем массив, в который мы добавили все наши новые значения в предыдущей части, newArr.sort (a, b) = ›ab.

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

В приведенном выше примере показан случай, когда нам предоставляется входной массив, мы циклически сохраняем возведенные в квадрат значения в отдельном массиве, а затем сортируем этот массив перед его возвратом, потому что условное выражение нашего решения возвращает true, когда оно проверяет первое значение во входном массиве и находит, что -5 меньше 0.

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

  1. Здесь мы создаем функцию, которая охватывает все наши тесты, и когда мы запускаем этот файл с помощью Node, эта функция будет выполнять все наши тесты для нашей функции sortedSquaredArray.
  2. Это наше возвращение. Не сообщает нам, верен он или нет, и даже не сообщает, к какому тесту относится результат.

Пока мы ничего не упростили, мы добавили только 3 строки кода: оболочку функции, конец блока, содержащего все наши тесты, и вызов этой тестовой функции. Что, если мы создадим вспомогательную функцию, которая принимает наш тестовый ввод и сравнивает его с нашим ожидаемым результатом, который мы уже прокомментировали под каждым тестом? Давай попробуем.

Хорошо, на этой картинке многое изменилось, поэтому позвольте мне рассказать о том, что произошло, шаг за шагом, потому что это действительно довольно просто.

  1. Я создал функцию runTest. Она вернет, возвращает ли sortedSquaredArray ожидаемое значение.
  2. runTest примет входной массив, который мы хотим протестировать, в качестве первого аргумента, а массив, который мы ожидаем вернуть и который мы ранее прокомментировали, в качестве второго аргумента.
  3. Здесь мы создаем функцию runTest и соответствующим образом маркируем параметры: input (массив, который мы тестируем, который будет передан в sortedSquaredArray) и expectedOutput (то, что мы ожидаем получить, если наше решение sortedSquaredArray является правильным).
  4. Функция runTest вызовет нашу функцию sortedSquaredArray и сохранит результат в переменной actualOutput. Затем мы сравниваем переменную actualOutput с аргументом expectedOutput и возвращаем значение при условии совпадения значений. Этот условный возврат будет записан в консоль.
  5. Не все наши тесты прошли.

Здесь важно отметить, что массивы хранятся по ссылке, и поэтому каждый массив уникален. Это означает, что мы должны преобразовать их во что-то еще, например, в строки, прежде чем мы сможем сравнивать.

Неплохо для начала, но есть немало улучшений, которые, я думаю, мы можем сделать, среди прочего, для удобочитаемости.
Прежде всего, мы повторяем console.log (runTest (input, expectedOutput); много раз, и его довольно сложно читать, поэтому я собираюсь убрать это.

  1. Я собираюсь поместить все наши входы и выходы в перечислимый список. Я решил использовать объект над массивом, чтобы упростить это, а также потому, что у нас есть переменное количество тестов. То есть мы можем добавить больше в будущем, и не имеет значения, в каком порядке выполняются тесты. Кроме того, мы можем использовать ключ, чтобы указать, какой тест дал конкретный результат.
  2. Здесь я просто проверяю, что получаю желаемый результат. То есть сообщение будет ссылаться на уникальный ключ объекта «tests» как ссылку на тест, который дал результат, а также будет регистрировать фактическое содержимое этого теста.

Теперь, когда мы знаем, что все работает до сих пор, нам нужно передать соответствующие значения в нашу функцию runTest. Кроме того, я передам ключ в качестве третьего аргумента в runTest, чтобы я мог ссылаться на него в своем сообщении об ошибке.

  1. Мы заменяем console.log () вызовом нашей функции runTest, передавая части нашего объекта по мере их перечисления. Кроме того, я добавил третий аргумент - ключ объекта, который я буду использовать в качестве идентификатора, чтобы определить, в каком тесте мы сейчас участвуем. Мы получаем в основном ту же информацию, которая передается в нашу функцию runTest, поэтому мне действительно нужно было только изменить обмен сообщениями, чтобы отразить идентификатор теста, который в настоящее время выполняется.
  2. Теперь мы можем видеть консольный журнал каждого теста по его идентификатору, успешно ли он прошел тест и почему не прошел, если применимо.

И я доволен тем, где сейчас находятся тесты. Есть еще кое-что, что мы можем сделать, чтобы сделать это более аккуратным, например, добавить фреймворки, такие как LoDash или Jest, или даже просто разделить тесты в другой файл и импортировать все различные версии нашего решения в этот тестовый файл. Затем мы можем протестировать все сразу, дать всему собственный тест на скорость или сделать все, что мы можем вообразить. И не думай, что я не… следующая статья, ха-ха!
Спасибо за чтение, и, как всегда, не стесняйтесь поделиться своими мыслями. Я все еще пытаюсь разобраться с лучшими практиками и т. д., и мне хотелось бы услышать ваши отзывы и мысли.