> For the complete documentation index, see [llms.txt](https://eda-1.gitbook.io/lgwt/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eda-1.gitbook.io/lgwt/osnovy-go/integers.md).

# Целые числа

[**Весь код для этой главы вы можете найти здесь**](https://github.com/quii/learn-go-with-tests/tree/main/integers)

Целые числа работают так, как вы и ожидаете. Давайте напишем функцию `Add`, чтобы попробовать это на практике. Создайте тестовый файл `adder_test.go` и напишите следующий код.

**Примечание:** Файлы исходного кода Go могут иметь только один `package` на директорию. Убедитесь, что ваши файлы организованы в отдельные пакеты. [Здесь приведено хорошее объяснение этому.](https://dave.cheney.net/2014/12/01/five-suggestions-for-setting-up-a-go-project)

Структура вашего проекта может выглядеть примерно так:

```
learnGoWithTests
    |
    |-> helloworld
    |    |- hello.go
    |    |- hello_test.go
    |
    |-> integers
    |    |- adder_test.go
    |
    |- go.mod
    |- README.md
```

## Сначала напишите тест

```go
package integers

import "testing"

func TestAdder(t *testing.T) {
	sum := Add(2, 2)
	expected := 4

	if sum != expected {
		t.Errorf("expected '%d' but got '%d'", expected, sum)
	}
}
```

Вы заметите, что мы используем `%d` в качестве форматной строки, а не `%q`. Это потому, что мы хотим напечатать целое число, а не строку.

Также обратите внимание, что мы больше не используем основной пакет (main package), вместо этого мы определили пакет с именем `integers`; как следует из названия, он будет группировать функции для работы с целыми числами, такие как `Add`.

## Попробуйте запустить тест

Запустите тест `go test`

Изучите ошибку компиляции

`./adder_test.go:6:9: undefined: Add`

## Напишите минимальное количество кода, чтобы тест запустился, и проверьте вывод ошибочного теста

Напишите столько кода, чтобы удовлетворить компилятор *и только это* — помните, мы хотим убедиться, что наши тесты завершаются с ошибкой по правильной причине.

```go
package integers

func Add(x, y int) int {
	return 0
}
```

Помните, что когда у вас есть несколько аргументов одного и того же типа (в нашем случае два целых числа), вместо `(x int, y int)` вы можете сократить это до `(x, y int)`.

Теперь запустите тесты, и мы должны быть довольны тем, что тест правильно сообщает об ошибке.

`adder_test.go:10: expected '4' but got '0'`

Если вы заметили, мы узнали о *именованном возвращаемом значении* в [предыдущем](/lgwt/osnovy-go/hello-world.md#onelastrefactor) разделе, но здесь его не используем. Его следует использовать, когда смысл результата не ясен из контекста; в нашем случае достаточно ясно, что функция `Add` будет складывать параметры. Вы можете обратиться к [этой](https://go.dev/wiki/CodeReviewComments#named-result-parameters) вики для получения более подробной информации.

## Напишите достаточно кода, чтобы тест прошел

В строжайшем смысле TDD мы должны теперь написать *минимальное количество кода, чтобы тест прошел*. Педантичный программист может сделать это:

```go
func Add(x, y int) int {
	return 4
}
```

Ага! Снова провал, TDD — это обман, не так ли?

Мы могли бы написать еще один тест с другими числами, чтобы заставить этот тест завершиться ошибкой, но это похоже на [игру в кошки-мышки](https://en.m.wikipedia.org/wiki/Cat_and_mouse).

Как только мы лучше ознакомимся с синтаксисом Go, я представлю технику, называемую *"Property Based Testing"* (тестирование на основе свойств), которая избавит разработчиков от проблем и поможет найти ошибки.

А пока давайте исправим это правильно:

```go
func Add(x, y int) int {
	return x + y
}
```

Если вы повторно запустите тесты, они должны пройти.

## Рефакторинг

В *текущем* коде не так много, что мы могли бы улучшить.

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

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

Вы можете добавить документацию к функциям с помощью комментариев, и они появятся в Go Doc так же, как вы смотрите документацию стандартной библиотеки.

```go
// Add takes two integers and returns the sum of them.
func Add(x, y int) int {
	return x + y
}
```

### Тестируемые примеры

Если вы действительно хотите приложить дополнительные усилия, вы можете создать [тестируемые примеры](https://blog.golang.org/examples). Вы найдете множество примеров в документации стандартной библиотеки.

Часто примеры кода, которые можно найти за пределами кодовой базы, например, в файле readme, устаревают и становятся неверными по сравнению с фактическим кодом, потому что они не проверяются.

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

Примерные функции начинаются с `Example` (подобно тому, как тестовые функции начинаются с `Test`) и находятся в файлах `_test.go` пакета. Добавьте следующую функцию `ExampleAdd` в файл `adder_test.go`.

```go
func ExampleAdd() {
	sum := Add(1, 5)
	fmt.Println(sum)
	// Output: 6
}
```

(Если ваш редактор не импортирует пакеты автоматически, шаг компиляции завершится ошибкой, потому что у вас будет отсутствовать `import "fmt"` в `adder_test.go`. Настоятельно рекомендуется изучить, как исправить такие ошибки автоматически в используемом вами редакторе.)

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

Запустив набор тестов пакета, мы видим, что функция `ExampleAdd` выполняется без каких-либо дополнительных настроек с нашей стороны:

```bash
$ go test -v
=== RUN   TestAdder
--- PASS: TestAdder (0.00s)
=== RUN   ExampleAdd
--- PASS: ExampleAdd (0.00s)
```

Обратите внимание на специальный формат комментария `// Output: 6`. Хотя пример всегда будет скомпилирован, добавление этого комментария означает, что пример также будет выполнен. Временно удалите комментарий `// Output: 6`, затем запустите `go test`, и вы увидите, что `ExampleAdd` больше не выполняется.

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

Чтобы просмотреть документацию примеров, давайте быстро взглянем на `pkgsite`. Прежде чем перейти в каталог вашего проекта, убедитесь, что вы установили `pkgsite`, выполнив следующую команду: `go install golang.org/x/pkgsite/cmd/pkgsite@latest`, затем запустите `pkgsite -open .`, которая должна открыть веб-браузер, указывающий на `http://localhost:8080`. Здесь вы увидите список всех пакетов стандартной библиотеки Go, а также сторонних пакетов, которые вы установили, среди которых вы должны увидеть документацию с примерами для `github.com/quii/learn-go-with-tests`. Перейдите по этой ссылке, затем посмотрите в разделе `Integers`, затем в разделе `func Add`, затем разверните `Example`, и вы должны увидеть пример, который вы добавили для `sum := Add(1, 5)`.

Если вы публикуете свой код с примерами по общедоступному URL-адресу, вы можете поделиться документацией своего кода на [pkg.go.dev](https://pkg.go.dev/). Например, [здесь](https://pkg.go.dev/github.com/quii/learn-go-with-tests/integers/v2) находится окончательная версия API для этой главы. Этот веб-интерфейс позволяет искать документацию по пакетам стандартной библиотеки и сторонним пакетам.

## Подведение итогов

Что мы рассмотрели:

* Больше практики рабочего процесса TDD
* Целые числа, сложение
* Написание лучшей документации, чтобы пользователи нашего кода могли быстро понять его использование
* Примеры использования нашего кода, которые проверяются как часть наших тестов


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://eda-1.gitbook.io/lgwt/osnovy-go/integers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
