Может ли процесс считывать свой собственный поток "out out"? - PullRequest
7 голосов
/ 15 марта 2019

Как бы процесс считывал свой собственный поток вывода?Я пишу автоматизированные тесты, которые запускают несколько подпроцессов приложений (приложений) в том же процессе, что и тест.Таким образом, стандартный вывод представляет собой сочетание результатов тестирования и вывода приложения.

Я хочу прочитать поток вывода во время выполнения и провалить тест, если я вижу ошибки из приложения.Это возможно / возможно?Если да, то как мне это сделать?

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

Также обратите внимание, что это не обман Как проверить вывод функции (stdout / stderr) в модульных тестах Go , хотя этот билет похож и полезен.Другой тикет о захвате вывода для одного вызова функции.Этот билет предназначен для непрерывного чтения всего потока.Правильный ответ тоже немного другой - для этого нужна труба.

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Да, вы можете использовать os.Pipe(), а затем обработать его самостоятельно:

tmp := os.Stdout
r, w, err := os.Pipe()
if err != nil {
    panic(err)
}
os.Stdout = w

Или перевести os.Stdout в другой файл или strings.Builder.
Вот подробный ответ:
Как в Go записать стандартный вывод функции в строку?

0 голосов
/ 15 марта 2019

Немного измененная версия ответа, указанного в В Go, как мне записать стандартный вывод функции в строку? , используя os.Pipe (форма IPC ):

Pipe возвращает подключенную пару файлов; читает из r возвращаемых байтов, записанных в w. Он возвращает файлы и ошибку, если таковые имеются.

Поскольку os.Stdout является * os.File , вы можете заменить его на любой файл.

 package main

 import (
    "bytes"
    "fmt"
    "io"
    "log"
    "os"
 )

 func main() {
    old := os.Stdout
    r, w, _ := os.Pipe() // TODO: handle error.
    os.Stdout = w

    // All stdout will be caputered from here on.

    fmt.Println("this will be caputered")

    // Access output and restore previous stdout.
    outc := make(chan string)

    go func() {
        var buf bytes.Buffer
        io.Copy(&buf, r) // TODO: handle error
        outc <- buf.String()
    }()

    w.Close()
    os.Stdout = old

    out := <-outc
    log.Printf("captured: %s", out)
 }
...