пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅ
По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:
Вы можете более эффективно запускать и компилировать свои программы с помощью этого удобного средства автоматизации.
Если при обновлении некоторых файлов вы хотите запускать или обновлять весь программный модуль, то для вас может оказаться полезной утилита
make
. Для нее требуется файл
Makefile
(или
makefile
), который определяет набор задач для выполнения. Вы могли уже использовать
make
, когда компилировали программу из исходного кода. Большая часть проектов с открытым исходным кодом использует
make
для того, чтобы скомпилировать конечный исполняемый бинарный файл, который в последствии можно будет установить с помощью команды
make install
.
В этой статье мы посмотрим, что же такое
make
и
Makefile.
Для этого приведем несколько простых и усложненных примерных задач. Прежде чем мы начнем, убедитесь, что
make
уже установлен в вашей системе.
Простые примеры
Давайте начнем с того, что напечатаем в терминале простое «Hello World!». Создайте пустой каталог
myproject
, который будет содержать файл
Makefile
, внутри которого будет записано следующее:
say_hello:
echo "Hello World"
А теперь запустите файл, набрав
make
внутри каталога
myproject
. Результат будет следующий:
$ make
echo "Hello World"
Hello World
В приведенном выше примере
say_hello
выступает в роли имени функции, подобно любому другому языку программирования. Это называется
целью (target)
.
Предварительные условия (prerequisites)
или
зависимости (dependencies)
соответствуют цели. Для простоты мы не определили никаких предварительных условий в данном примере. Команда
echo "Hello World"
называется
рецептом (recipe)
.
Рецепт
использует
предварительные условия
для формирования
цели
. Цель, предварительные условия и рецепты вместе формируют
правило (rule)
.
Подытожим сказанное. Ниже представлен синтаксис обычного правила:
target: prerequisites
recipe
Скажем, целью может быть двоичный файл, который зависит от предварительных условий (файлов с исходным кодом). В свою очередь, предварительное условие тоже может быть целью, которая имеет другие зависимости:
final_target: sub_target final_target.c
Recipe_to_create_final_target
sub_target: sub_target.c
Recipe_to_create_sub_target
Цель – это не обязательно файл; это может быть просто название рецепта, как в нашем примере. Мы это называем «абстрактными целями».
Возвращаясь к примеру выше, при выполнении
make
отображалась целая команда
echo "Hello World"
, а только потом уже фактический вывод команды. Зачастую нам такое не нужно. Чтобы сама команда не отображалась, ввод команды
echo
нужно начать с
@
:
say_hello:
@echo "Hello World"
Теперь попробуйте запустить
make
снова. В выводе останется только следующее:
$ make
Hello World
Давайте добавим несколько абстрактных целей (
generate
и
clean
) в
Makefile
:
say_hello:
@echo "Hello World"
generate:
@echo "Creating empty text files..."
touch file-{1..10}.txt
clean:
@echo "Cleaning up..."
rm *.txt
Если мы попробуем запустить
make
после того, как внесли в него изменения, то увидим, что выполнится только цель
say_hello
. Это происходит по той причине, что только первая цель в make-файле является целью по умолчанию. То, что называется
целью по умолчанию (default goal)
, послужило причиной для того, чтобы в качестве первой цели в большинстве проектов использовалась цель
all
.
all
ответственна за то, чтобы вызывать другие цели. При этом такое развитие событий можно переиграть с помощью специальной абстрактной цели под названием
.DEFAULT_GOAL
.
Давайте добавим ее в начало нашего make-файла:
.DEFAULT_GOAL := generate
Это запустит цель
generate
в качестве цели по умолчанию:
$ make
Creating empty text files...
touch file-{1..10}.txt
Как можно понять из названия, абстрактная цель
.DEFAULT_GOAL
может запустить только одну цель за раз. Именно поэтому большинство make-файлов в качестве цели используют
all
, которая может вызывать столько целей, сколько необходимо.
Давайте добавим абстрактную цель
all
и уберем
.DEFAULT_GOAL
:
all: say_hello generate
say_hello:
@echo "Hello World"
generate:
@echo "Creating empty text files..."
touch file-{1..10}.txt
clean:
@echo "Cleaning up..."
rm *.txt
Прежде чем запустить
make
, давайте добавим еще одну абстрактную цель
.PHONY
, в которой мы определим все цели, которые не являются файлами.
make
запустит свой рецепт вне зависимости от того, есть ли файл с таким именем или каково время его последнего изменения. Вот так будет выглядеть готовый make-файл:
.PHONY: all say_hello generate clean
all: say_hello generate
say_hello:
@echo "Hello World"
generate:
@echo "Creating empty text files..."
touch file-{1..10}.txt
clean:
@echo "Cleaning up..."
rm *.txt
make вызовет say_hello и generate:
$ make
Hello World
Creating empty text files...
touch file-{1..10}.txt
Это обычная практика не вызывать
clean
в
all
или ставить его в качестве первой цели.
clean
должен вызываться вручную только тогда, когда в качестве первого аргумента для
make
нужна очистка:
$ make clean
Cleaning up...
rm *.txt
Теперь, когда вы имеете представление о том, как работает простой make-файл и как его можно написать, давайте рассмотрим несколько более сложных примеров.
Усложненные примеры
Переменные
В примере выше большая часть целевых и предварительных переменных являются неизменяемыми, но в реальных проектах они заменяются переменными и шаблонами.
Самый простой способ определить переменную в make-файле – использовать оператор =. Например, вот так выглядит присваивание команды
gcc
переменной
CC
:
CC = gcc
Также она называется
рекурсивной расширенной переменной (recursive expanded variable)
, и ее можно использовать в правиле:
hello: hello.c
${CC} hello.c -o hello
И как вы уже, наверное, догадались, при передаче в терминал в рецепте появляется дополнительный текст:
gcc hello.c -o hello
И
${CC}
, и
$(CC)
являются допустимыми ссылками для вызова
gcc
. Но если кто-то попробует переприсвоить переменную самой себе, то получится бесконечный цикл. Давайте проверим:
CC = gcc
CC = ${CC}
all:
@echo ${CC}
При запуске
make
получим следующее:
$ make
Makefile:8: *** Recursive variable 'CC' references itself (eventually). Stop.
Чтобы избежать такой ситуации, можно воспользоваться оператором := (это будет называться
простой расширенной переменной (simply expanded variable)
). И у нас не должно возникнуть проблем при запуске следующего make-файла:
CC := gcc
CC := ${CC}
all:
@echo ${CC}
Шаблоны и функции
Следующий make-файл может скомпилировать любую программу на C с помощью переменных, шаблонов и функций. Давайте рассмотрим его, строчку за строчкой:
# Usage:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # compiler to use
LINKERFLAG = -lm
SRCS := $(wildcard *.c)
BINS := $(SRCS:%.c=%)
all: ${BINS}
%: %.o
@echo "Checking.."
${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
@echo "Creating object.."
${CC} -c $<
clean:
@echo "Cleaning up..."
rm -rvf *.o ${BINS}
Строки начинаются с
#
. Это комментарии.
Строка
.PHONY = all clean
определяет абстрактные цели
all
и
clean
.
Переменная
LINKERFLAG
определяет флаги, которые будут использоваться в рецепте вместе с
gcc
.
SRCS := $(wildcard *.c)
:
$(wildcard pattern)
- это одна из
функций для файловых имен
. В данной случае, все файлы с расширением
.c
будут хранится в переменной
SRCS
.
BINS := $(SRCS:%.c=%)
: это называется ссылкой с заменой. В данной случае, если
SRCS
будет иметь значение
'foo.c bar.c'
, то значение для
BINS
будет следующее:
'foo bar'
.
Строка
all: ${BINS}
: абстрактная цель
all
вызывает значения в
${BINS}
как отдельные цели.
Правило:
%: %.o
@echo "Checking.."
${CC} ${LINKERFLAG} $< -o $@
Чтобы понять это правило, давайте взглянем на пример. Предположим, что
foo
- это одно из значений
${BINS}
. Отождествим
%
с
foo
(
%
можно отождествить с любым именем цели). Ниже приведено правило в полной форме:
foo: foo.o
@echo "Checking.."
gcc -lm foo.o -o foo
Как показано выше,
%
заменяется
foo
.
$<
заменяется
foo.o
.
$<
выполняет соответствие по образцу с предварительными условиями, а
$@
отождествляется с целью. Это правило будет вызвано для каждого значения в
${BINS}
.
Правило:
%.o: %.c
@echo "Creating object.."
${CC} -c $<
Каждое предварительное условие в предыдущем правиле считается целью для этого правила. Ниже приведено правило в полной форме:
foo.o: foo.c
@echo "Creating object.."
gcc -c foo.c
И наконец, мы удаляем все двоичные и объектные файлы в цели
clean
.
Ниже приведен переписанный make-файл, который мы рассматривали выше, из расчета, что он находится в каталоге с единственным файлом
foo.c
:
# Usage:
# make # compile all binary
# make clean # remove ALL binaries and objects
.PHONY = all clean
CC = gcc # compiler to use
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
all: foo
foo: foo.o
@echo "Checking.."
gcc -lm foo.o -o foo
foo.o: foo.c
@echo "Creating object.."
gcc -c foo.c
clean:
@echo "Cleaning up..."
rm -rvf foo.o foo
git config
- это мощная команда Git. Вы можете использовать файл конфигурации Git для того, чтобы подстроить Git под себя.
Этот файл находится на уровне проекта, в котором был запущен Git (
/project/.git/config
), или на корневом уровне (
~/.gitconfig
). Если в нем не указаны никакие конфигурации, то это значит, что Git использует настройки по умолчанию.
Из этой статьи вы узнаете о некоторых полезных конфигурациях Git, которые помогут вам оптимизировать ваш процесс разработки. Все советы, которыми я здесь поделюсь, когда-то помогли мне. Существует также множество других вещей, которые вы сможете опробовать уже после того, как прочитаете эту статью.
Советы по конфигурациям Git
Ниже представлены несколько масштабных советов по конфигурациям Git.
1. Выберите для Git редактор по умолчанию
Когда вы пытаетесь сделать коммит в Git, то он по умолчанию открывает редактор
vi
, который выглядит вот так:
Этот редактор может оказаться не таким простым, и если вы хоть чем-то похожи на меня, то будете использовать тот редактор для написания коммитов, который вам больше нравится. В файле
~/.gitconfig
вам нужно добавить следующее:
[core]
editor = code --wait
или вы можете воспользоваться командой оболочки:
git config --global core.editor "code --wait"
Эта конфигурация указывает Git, что для операций по типу коммитов и тегов мы будем использовать свой редактор VSCode.
Что касается других редакторов, вам поможет следующая таблица:
Конфигурация редактора для Git
2. Очистка Git в процессе выборки
Знаете ли вы что делает команда очистки в процессе выборки?
Если кратко, то очистка в процессе выборки – это метод очистки, который, когда вы выполняете команду
git fetch --prune
, удаляет все устаревшие и давно ненужные ссылки в вашем каталоге
.git
.
Автоматизировать этот процесс можно не только с помощью параметра
--prune
, но и путем добавления в
~/.gitconfig
следующих строк:
[fetch]
prune = true
или с помощью следующей команды:
git config --global fetch.prune true
При этом очистка будет производиться каждый раз, когда вы будете выполнять команду
git fetch
.
3. Псевдонимы Git
В файле конфигурации Git вы можете добавить псевдонимы для некоторых длинных команд, которые вы используете регулярно. Например, для коммитов, тайников и т.д.
Предположим, что вы хотите создать псевдоним для добавления пустого коммита. В таком случае вам нужно добавить в файл конфигурации следующее:
[alias]
empty = "git commit --allow-empty"
или ввести в терминале следующую команду:
git config --global alias.empty "git commit --allow-empty"
И вы сможете использовать команду вот таким образом:
git empty "Empty commit"
Кроме того, вы можете добавить псевдонимы для команд, которые используются вне Git. Например, вот так можно создать псевдоним, который удаляет локальные ветки, которые перешли в разряд удаленных:
[alias]
delete-local-merged = "!git fetch && git branch --merged | egrep -v 'master' | xargs git branch -d"
Восклицательный знак «!» указывает на то, что Git должен запустить эту команду как команду оболочки, а не как команду
git *
.
Команду
git fetch
мы используем для псевдонима. После чего мы получаем объединенные ветки, передаем их команде
egrep
в качестве входных данных, фильтруем ветку main и удаляем ветки.
4. Настройка ветки по умолчанию
Когда вы инициализируете репозитрий (
git init
), веткой по умолчанию является ветка
master
. На сегодняшний день многие разработчики предпочитают, чтобы на этом месте была ветка
main
или какая-то другая.
При этом вам не нужно создавать новую ветку с именем
main
, удалять ветку
master
и использовать
main
как ветку по умолчанию. Это слишком долго. В файле конфигурации вы можете записать следующее и при инициализации Git установить, таким образом, ветку по умолчанию.
[init]
defaultBranch = main (или любое другое имя, которое вы хотите)
В таком случае команда
git init
сделает так, что веткой по умолчанию будет ветка
main
.
5. Демонстрация краткого статуса по умолчанию
По умолчанию команда
git status
демонстрирует вам подробно описанные изменения в вашем проекте. А именно вот в таком формате:
On branch [branch name]
Your branch is up to date with ...
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in the working directory)
modified: ...
Untracked files:
(use "git add ..." to include in what will be committed)
...
no changes added to commit (use "git add" and/or "git commit -a")
Это довольно полезно, но иногда вам требуется лишь краткий отчет о состоянии репозитория. В этом вам поможет флаг
--short
, который необходимо добавить к команде
git status
. Результат выполнения такой команды будет следующий:
M [file]
?? [file]
«M» означает «modified», то есть «измененный», а «??» - неотслеживаемый. Мы можем сделать еще лучше, установив такой формат вывода как вывод по умолчанию. Для этого необходимо установить следующую конфигурацию:
[status]
short = true
Заключение
В этом списке мы рассмотрели пять способов, как можно оптимизировать процесс разработки за счет настройки стандартной работы Git, и это далеко не полный список.
Любое приложение или ПО прежде чем попасть к пользователю тестируется инженером. Под эти задачи необходим отдельный специалист или команда. Базово тестирование можно разделить на ручное и автоматизированное. Разница заключается в том, что в первом случае тестировщик вручную имитирует поведение пользователя и проверяет функционал. Во втором случае специалист пишет специальную программу. Чтобы ее составить, специалист должен разбираться в основах одного из языков программирования. Это может быть Java или Python.
Ручное и автоматизированное тестирование — это дополняющие друг друга направления. Их объединяет общая цель — проверить программу так, чтобы она работала без сбоев. Новые функции, как правило, тестируют вручную. Но если проект становится большим и продолжает расти, автоматизатор пишет под него тесты для быстроты проверки. В этом материале мы рассмотрим подробнее профессию автоматизатора тестирования: как им стать, какие навыки необходимы на старте и уровень дохода.
Тестировщик, QA-инженер, QA-автоматизатор,
QA-мануальщик
— разбираемся в понятиях
Тестировщик и QA-специалист — это разные специальности, хотя их часто путают и объединяют в одну.
Тестировщик
проверяет готовое программное обеспечение, он не влияет на ход создания продукта, а только тестирует и фиксирует ошибки. Работа тестировщиком считается одной
из самых доступных и легких для входа в IT, потому что не требует навыков программирования.
QA или
Quality Assurance расшифровывается как «обеспечение качества».
QA-инженер
отвечает за тестирование и качество продукта на всех этапах его создания. В отличие от тестировщика QA-специалист активно участвует в веб-разработке программного обеспечения и может использовать не только существующие инструменты тестирования, но и самостоятельно разрабатывать и внедрять их.
Если углубиться в специальность QA-инженера, то на рынке IT-вакансий можно
найти вакансии для QA-мануальщиков и QA-автоматизаторов.
QA-мануальщик
(Manual QA Engineer) или ручной тестировщик –
специалист, который ищет ошибки без использования специальных программ. Он имитирует реальное поведение пользователя, чтобы найти баги и охватить максимум функций продукта.
И вот, наконец, мы добираемся до
QA-автоматизатора
(Automation QA Engineer). Это точно такой же тестировщик, который имитирует поведение пользователей, но при помощи скриптов. Они позволяют быстро прогнать тысячи рутинных тестов. Как мы уже упоминали выше, ручное и автоматизированное тестирование – это пересекающиеся процессы.
Роль автоматизатора тестирования
Увеличение эффективности тестирования: автоматизатор тестирования работает над тем, чтобы тесты выполнялись быстрее и более точно, освобождая ресурсы для других задач, таких как анализ результатов и улучшение процесса разработки.
Улучшение качества ПО: автоматическое тестирование обеспечивает широкое покрытие тестами, что помогает выявлять ошибки и проблемы в коде на ранних стадиях разработки.
Экономия времени и ресурсов: в отличие от ручного тестирование, автоматизация сокращает время и снижает затраты на разработку и поддержку ПО.
Что нужно уметь на старте
Автоматизатор тесно сотрудничает с командой разработчиков и ручными тестировщиками. Для успешной работы QA-автоматизатору необходимо обладать следующими hard skills:
— основы тестирования ПО и типы тестов;
— основы программирования;
— инструменты автоматизации тестирования;
— основы тестирования API и
автоматизация UI тестирования;
— понимание жизненного цикла разработки ПО;
— умение работать с командной строкой, написание скриптов для автоматизации рутинных задач.
Не стоит забывать про софт-скилы, которые важны для построения любой карьеры. Это склонность к самообучению, коммуникабельность, креативность, умение работать в команде, ответственность и структурное мышление.
Как стать
QA-автоматизатором
Самое главное — освоить навыки тестирования. Начать можно с онлайн-курсов, учебных материалов и практических заданий, чтобы получить необходимые знания и опыт. На нашей платформе Merion Academy можно ознакомиться
со списком курсов
в этой области и пройти бесплатные вводные уроки. Например, у нас есть
курс по основам QA с нуля
. При наличии опыта в ручном тестировании можно стартовать в профессии.
Уровень дохода автоматизатора тестирования
На апрель 2024 года по запросу вакансий в сфере QA (сюда входят автотестировщики, ручные тестировщики, а также QA-инженеры) на агрегаторе hh.ru можно найти 4 334 вакансии.
Медианные зарплаты тестировщиков на 1 марта 2024 года составляют:
—
47 тыс. рублей в месяц – стажеры.
— 66 тыс. рублей в месяц — специалисты уровня junior.
— 137 тыс. рублей в месяц — уровень middle.
— 232 тыс. рублей в месяц — уровень senior.
— 265 тыс. рублей в месяц — уровень Lead и руководители QA-отделов.
Профессия автоматизатора требует глубоких знаний в тестировании, основ программирования и процессов автоматизации, а также системности мышления. В то же время это очень креативная профессия, в которой можно развернуть свой творческий потенциал через решение нестандартных задач.
