Юнит Тесты для Калькулятора

Добрый день на другом вопросе помогли, с решением калькулятора всем за спасибо за помощь шас у меня такая задача написать Юнит тесты для калькулятора написал тест кейсы и методы для проверки, но при запуске код не запускается, не знаю почему. Ошибка 1 Ошибка

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp12
{
    public class Program
    {
        public static void Main(string[] args)
        {

            try
            {
                double a, b = 0;
                char z;
                Console.Write("Введите 1 число ");
                a = double.Parse(Console.ReadLine());
                Console.Write("Введите действие (+, -, *, /, s(Корен)) ");
                z = Console.ReadKey().KeyChar;
                Console.WriteLine();
                if (z != 's')
                {
                    Console.Write("Введите 2 число ");
                    b = double.Parse(Console.ReadLine());
                }
                switch (z)
                {
                    case '+':
                        Console.WriteLine("{0}+{1}={2}", a, b, a + b);
                        break;
                    case '-':
                        Console.WriteLine("{0}-{1}={2}", a, b, a - b);
                        break;
                    case '*':
                        Console.WriteLine("{0}*{1}={2}", a, b, a * b);
                        break;
                    case '/':
                        try
                        {
                            if (b == 0)
                                throw new DivideByZeroException();
                            Console.WriteLine("{0}/{1}={2}", a, b, a / b);
                        }
                        catch (DivideByZeroException ex)
                        {
                            Console.WriteLine("Делить на ноль нельзя");

                        }
                        break;
                    case 's':
                        Console.WriteLine("Корен({0})={1}", a, Math.Sqrt(a));
                        break;
                    default:
                        Console.WriteLine("Ошибка");
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey();
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UnitTestProject5
{
    class Logic
    {
        public double Sum(double a, double b)
        {
            return a + b;
        }
        public double Diff(double a, double b)
        {
            return a - b;
        }
        public double Mult(double a, double b)
        {
            return a * b;
        }
        public double Div(double a, double b)
        {
            return a / b;
        }
        public double Koren(double a)
        {
            return Math.Sqrt(a);
        }
    }

}
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitTestProject5;

namespace UnitTestProject1
{
    class Class2 : Logic
    {
        [TestCase(5, 7, 12)]
        [TestCase(1, 2.5, 3.5)]
        [TestCase(100, -1, 99)]
        [TestCase(10, -100, -90)]
        public void TestSum(double a, double b, double exp)
        {
            double act = Sum(a, b);
            Assert.AreEqual(exp, act);
        }
        [TestCase(8, 5, 3)]
        [TestCase(9, 12, -3)]
        [TestCase(25, 20, 5)]
        [TestCase(10, 2, 8)]
        public void TestDiff(double a, double b, double exp)
        {
            double act = Diff(a, b);
            Assert.AreEqual(exp, act);
        }
        [TestCase(2, 5, 10)]
        [TestCase(5, 3, 15)]
        [TestCase(12, 10, 120)]
        [TestCase(10, 3, 30)]
        public void TestMult(double a, double b, double exp)
        {
            double act = Mult(a, b);
            Assert.AreEqual(exp, act);
        }
        [TestCase(6, 2, 3)]
        [TestCase(133, 1, 133)]
        [TestCase(35, 5, 7)]
        [TestCase(220, 2, 110)]
        public void TestDiv(double a, double b, double exp)
        {
            double act = Div(a, b);
            Assert.AreEqual(exp, act);
        }
        [TestCase(4, 2)]
        [TestCase(9, 3)]
        [TestCase(25, 5)]
        [TestCase(16, 4)]
        public void TestSqrt1(double a, double exp)
        {
            double act = Koren(a);
            Assert.AreEqual(exp, act);
        }
    }

}

Ответы (1 шт):

Автор решения: Alexander Petrov

Судя по комментариям, вы хотите чего-то странного.

Модульные тесты используют только разработчики, они никогда не поставляются вместе с приложением конечному пользователю. Соответственно, юнит-тесты никак не должны запускаться вместе с приложением.

Причём модульные тесты пишутся для тестирования какого-либо модуля. В данном случае - калькулятора, а не всего приложения.

Вы поняли, что протестировать код, помещённый в метод Main не получается, поэтому выделили отдельный модуль Logic. Его нужно переименовать в "калькулятор":

public class Calculator
{
    public double Add(double a, double b)
    {
        return a + b;
    }
    public double Subtract(double a, double b)
    {
        return a - b;
    }
    public double Multiply(double a, double b)
    {
        return a * b;
    }
    public double Divide(double a, double b)
    {
        return a / b;
    }
    public double SquareRoot(double d)
    {
        return Math.Sqrt(d);
    }
}

Теперь сделаем юнит-тесты для этого модуля-калькулятора. Они должны быть в отдельной сборке (проекте).

Чтобы класс калькулятора был виден в тестах, нужно к проекту тестов добавить ссылку на сборку (Add Reference) с классом Calculator.

[TestFixture]
public class CalculatorTests
{
    [TestCase(5, 7, 12)]
    [TestCase(1, 2.5, 3.5)]
    [TestCase(100, -1, 99)]
    [TestCase(10, -100, -90)]
    public void Add_Numbers_ReturnsSum(double a, double b, double expected)
    {
        // Arrange
        var calc = new Calculator();

        // Act
        var actual = calc.Add(a, b);

        // Assert
        Assert.AreEqual(expected, actual);
    }
    [TestCase(8, 5, 3)]
    [TestCase(9, 12, -3)]
    [TestCase(25, 20, 5)]
    [TestCase(10, 2, 8)]
    public void Subtract_Numbers_ReturnsDifference(double a, double b, double expected)
    {
        var calc = new Calculator();

        double actual = calc.Subtract(a, b);

        Assert.AreEqual(expected, actual);
    }
    [TestCase(2, 5, 10)]
    [TestCase(5, 3, 15)]
    [TestCase(12, 10, 120)]
    [TestCase(10, 3, 30)]
    public void Multiply_Numbers_ReturnsProduct(double a, double b, double expected)
    {
        var calc = new Calculator();

        var actual = calc.Multiply(a, b);

        Assert.AreEqual(expected, actual);
    }
    [TestCase(6, 2, 3)]
    [TestCase(133, 1, 133)]
    [TestCase(35, 5, 7)]
    [TestCase(220, 2, 110)]
    public void Divide_Numbers_ReturnsQuotient(double a, double b, double expected)
    {
        var calc = new Calculator();

        double actual = calc.Divide(a, b);

        Assert.AreEqual(expected, actual);
    }
    [TestCase(4, 2)]
    [TestCase(9, 3)]
    [TestCase(25, 5)]
    [TestCase(16, 4)]
    public void SquareRoot_Number_ReturnsResult(double d, double expected)
    {
        var calc = new Calculator();

        double actual = calc.SquareRoot(d);

        Assert.AreEqual(expected, actual);
    }
}

Я постарался дать именования, соответствующие рекомендациям

Обратите внимание, у нас ещё нет приложения, которое использует калькулятор. А тесты уже можно прогнать.

Для работы тестов необходим NUnit3TestAdapter. Нужно установить либо расширение к Visual Studio, либо пакет в проект с тестами.


Перепишем код приложения, задействовав в нём наш калькулятор.

static void Main(string[] args)
{
    try
    {
        Console.Write("Введите 1 число ");
        double a = double.Parse(Console.ReadLine());

        Console.Write("Введите действие (+, -, *, /, s(Корен)) ");
        char operation = Console.ReadKey().KeyChar;
        Console.WriteLine();

        double b = 0;
        if (operation != 's')
        {
            Console.Write("Введите 2 число ");
            b = double.Parse(Console.ReadLine());
        }

        var calc = new Calculator();

        switch (operation)
        {
            case '+':
                Console.WriteLine("{0}+{1}={2}", a, b, calc.Add(a, b));
                break;
            case '-':
                Console.WriteLine("{0}-{1}={2}", a, b, calc.Subtract(a, b));
                break;
            case '*':
                Console.WriteLine("{0}*{1}={2}", a, b, calc.Multiply(a, b));
                break;
            case '/':
                try
                {
                    Console.WriteLine("{0}/{1}={2}", a, b, calc.Divide(a, b));
                }
                catch (DivideByZeroException)
                {
                    Console.WriteLine("Делить на ноль нельзя");
                }
                break;
            case 's':
                Console.WriteLine("Корень ({0})={1}", a, calc.SquareRoot(a));
                break;
            default:
                Console.WriteLine("Ошибка");
                break;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    Console.ReadKey();
}

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

введите сюда описание изображения



Конечно, эти тесты по сути бесполезны, т. к. по сути они проверяют работу встроенных команд процессора, но для обучения годятся.

Гораздо более интересным вариантом является написание, например, калькулятора, который принимает параметры в виде строк текста, парсит и вычисляет. Или можно добавить отдельный класс парсера. И, естественно, покрыть их тестами.

А можно ли протестировать метод Main и вообще код, принимающий ввод пользователя? Можно. Но там довольно сильное колдунство. Если есть желание - задайте отдельный вопрос.

→ Ссылка