【问题标题】:Remove logging the origin line in Jest删除在 Jest 中记录原始行
【发布时间】:2019-01-04 10:30:05
【问题描述】:

Jest 有这个功能来记录输出到console 方法的行。

在某些情况下,这可能会变得烦人:

  console.log _modules/log.js:37
  ℹ login.0 screenshot start

  console.time _modules/init.js:409
  login.0.screenshot: 0.33ms

  console.time _modules/init.js:394
  0 | login.0: 0.524ms

  console.log _modules/log.js:37
  ℹ login.1 screenshot start

知道如何关闭它吗?

【问题讨论】:

  • 这能回答你的问题吗? How to disable Jest `console.log` tags
  • @yentsun 显然不是;只有一个答案,它引用了下面的答案,并以不使用 Jest 结束。副本应该让读者 to 回答,而不是 来自 他们。
  • 这个问题仍然是旧问题的重复。

标签: javascript node.js logging jestjs


【解决方案1】:

使用 Jest 24.3.0 或更高版本,您可以在纯 TypeScript 中执行此操作,方法是将以下内容添加到在 setupFilesAfterEnv 中配置的 Jest 设置文件中:

import { CustomConsole, LogType, LogMessage } from '@jest/console';

function simpleFormatter(type: LogType, message: LogMessage): string {
    const TITLE_INDENT = '    ';
    const CONSOLE_INDENT = TITLE_INDENT + '  ';

    return message
        .split(/\n/)
        .map(line => CONSOLE_INDENT + line)
        .join('\n');
}

global.console = new CustomConsole(process.stdout, process.stderr, simpleFormatter);

【讨论】:

  • 在 JavaScript 中可以做到这一点吗?我有一个不使用 Babel 或 TypeScript 的简单 ES6 项目。
  • 此选项在 ES6 项目中不起作用。 (但下一条评论会)
【解决方案2】:

Jest 将基于可扩展 Console class 的自定义控制台实现注入测试全局范围。通常,它会在打印消息的同时提供有用的调试信息,回答可能不需要的输出来自何处的问题。

如果出于某种原因不希望这样做,检索默认 console 实现的一种简单方法是从 Node 内置模块中导入它。

可以针对特定的控制台调用完成:

let console = require('console');    
...
console.log(...)

对于在一系列测试中发生的许多问题:

const jestConsole = console;

beforeEach(() => {
  global.console = require('console');
});

afterEach(() => {
  global.console = jestConsole;
});

等等。

【讨论】:

  • 当测试并行运行时(jest 的默认行为),Jest 使用其自定义控制台实现来批处理测试输出并在每次测试后一次性打印出来。您的方法打破了这一点,导致测试输出交错。
  • 感谢您的反对投票。输出确实会交织,我没有说相反的。是否需要由开发人员决定,但我认为如果目的是提供香草控制台输出是有道理的,如果日志没有实时出现,则更难跟踪日志。我不完全理解来自 OP 的原始行的问题,但根据我的经验,延迟日志对于长时间的测试可能会很烦人。
  • 这正是我在这里寻找的:stackoverflow.com/q/67861269/1993761。刚刚试了一下,效果很好。
【解决方案3】:

更新:对于较新版本的 Jest,请参阅 Harald Wellmann 的回答。


查看 Jest 的 source code,似乎没有一种巧妙的方法可以关闭这些消息。

但是,一种可能的解决方案是编写您自己的控制台。在这里,我使用来自 Jest 的 Console.js 作为起点,然后创建了满足您需要的 SimpleConsole(为简单起见,我删除了一些终端着色功能,但您可以自己添加它们)。

添加到您的项目后,您可以在运行测试之前用自己的覆盖 Jest 的普通控制台:

const { SimpleConsole } = require('./SimpleConsole');
global.console = new SimpleConsole(process.stdout, process.stderr);

我制作了一个REPL 来展示它的实际效果。

SimpleConsole的源代码:

const path = require('path');
const assert = require('assert');
const {format} = require('util');
const {Console} = require('console');

function simpleFormatter() {
  const TITLE_INDENT = '    ';
  const CONSOLE_INDENT = TITLE_INDENT + '  ';

  return (type, message) => {
    message = message
      .split(/\n/)
      .map(line => CONSOLE_INDENT + line)
      .join('\n');

    return (
      message +
      '\n'
    );
  };
};

class SimpleConsole extends Console {
  constructor(stdout, stderr, formatBuffer) {
    super(stdout, stderr);
    this._formatBuffer = formatBuffer || simpleFormatter();
    this._counters = {};
    this._timers = {};
    this._groupDepth = 0;
  }

  _logToParentConsole(message) {
    super.log(message);
  }

  _log(type, message) {
    if (process.stdout.isTTY) {
      this._stdout.write('\x1b[999D\x1b[K');
    }
    this._logToParentConsole(
      this._formatBuffer(type, '  '.repeat(this._groupDepth) + message),
    );
  }

  assert(...args) {
    try {
      assert(...args);
    } catch (error) {
      this._log('assert', error.toString());
    }
  }

  count(label = 'default') {
    if (!this._counters[label]) {
      this._counters[label] = 0;
    }

    this._log('count', format(`${label}: ${++this._counters[label]}`));
  }

  countReset(label = 'default') {
    this._counters[label] = 0;
  }

  debug(...args) {
    this._log('debug', format(...args));
  }

  dir(...args) {
    this._log('dir', format(...args));
  }

  dirxml(...args) {
    this._log('dirxml', format(...args));
  }

  error(...args) {
    this._log('error', format(...args));
  }

  group(...args) {
    this._groupDepth++;

    if (args.length > 0) {
      this._log('group', chalk.bold(format(...args)));
    }
  }

  groupCollapsed(...args) {
    this._groupDepth++;

    if (args.length > 0) {
      this._log('groupCollapsed', chalk.bold(format(...args)));
    }
  }

  groupEnd() {
    if (this._groupDepth > 0) {
      this._groupDepth--;
    }
  }

  info(...args) {
    this._log('info', format(...args));
  }

  log(...args) {
    this._log('log', format(...args));
  }

  time(label = 'default') {
    if (this._timers[label]) {
      return;
    }

    this._timers[label] = new Date();
  }

  timeEnd(label = 'default') {
    const startTime = this._timers[label];

    if (startTime) {
      const endTime = new Date();
      const time = endTime - startTime;
      this._log('time', format(`${label}: ${time}ms`));
      delete this._timers[label];
    }
  }

  warn(...args) {
    this._log('warn', format(...args));
  }

  getBuffer() {
    return null;
  }
}

module.exports.SimpleConsole = SimpleConsole;

【讨论】:

  • 我会试试的。非常感谢!
  • 覆盖默认控制台会破坏 Jest --silent 选项
  • 完美。就是我要找的!!非常感谢。
猜你喜欢
  • 2019-07-24
  • 1970-01-01
  • 2015-03-04
  • 2017-09-23
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
相关资源
最近更新 更多