`
richie.lee
  • 浏览: 28896 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Jmockit用户指南中文翻译(未校对)之三

阅读更多
  • 严格和非严格的期望

在期望块new Expectations(){...}中,默认所有被记录下来的期望都是严格的。这意味着,这些期望的调用必须在重播阶段被执行,而且需要按照声明的期 望指定的执行顺序执行,而且,也只允许这些调用被执行。任何一个没有被记录下来的非期望调用都会造成测试用例失败。

另一方面,当我们需要记录(录制)非严格(或者是松散)的期望时,那么我们可以使用mockit.NonStrictExpectations子 类。在一个非严格的期望块中,所有的被mock的类型的所有调用都可以在重播阶段执行,当然包括不在期望中声明的。也就是说,默认情况下,在重播阶段是否 执行mock类型的调用是不会造成测试用例失败的。同样,这种不严格的期望是不要求调用的执行顺序的。

缺省情况下,一个严格的期望会精确匹配重播阶段的一个调用。换而言之,这类型的期望是存在一个隐式的调用次数约束1,就好像它后面紧跟着 times=1这个约束。而另一方面,对于一个非严格的期望,默认是可以匹配重播阶段调用的任意次数的。它存在一个隐式的调用次数下限为0的约束,就好 像,被指定约束minTimes=0.然而,无论哪种情况,隐式的调用次数约束是可以被显式的约束(相当于使用times/minTimes /maxTimes 属性字段)覆盖的。所以,一个严格的期望也可以被设置成允许任何调用次数的约束,同样,非严格的期望约束也可以反过来(当然,其前提是我们确实需要这 样)。

请注意,对于一个严格的期望,所有在重播阶段被期望所匹配的调用,都会隐式被校验通过的。剩余的调用则被认为不符合期望(即造成测试失败),除非, 这个mock的类型被关联到一个非严格的期望上。所以,使用隐式验证的严格期望需要排除verification块的使用,这个块是用于调用的显式校验 的。实际上,在 new Verifications() {...}代码块中,只有那些匹配非严格期望的调用才被允许使用。同样,那些非严格的mock类型中的调用(没有被期望声明的)也可以显式记录。

为了允许在new Expectations(){...}代码块中混合使用严格和非严格调用,我们提供了一个mockit.NonStric注解用于mock属性域或者参 数。任何一个这样的mock类型都可以被认为是一个非严格期望,同时所有没有被录制的调用都可以运行在重播阶段执行(就是说,它们不被认为是非期望的执 行,因此不会造成测试失败)。这是特别有用的,以避免需要记录调用构造函数,或任何不感兴趣的方法。

在一个期望代码块中,一个独立的期望可以通过在调用语句后加上notStrict()方法将该期望标记为非严格期望,尽管在大多数情况下,使用non-strict期望块或者使用non-strict注解mock字段/参数会比这种方式更容易简单。

因此,对于给定一个测试,我们怎么在严格和非严格期望之间进行选择呢?这里没有普遍正确的答案。这通常会依赖于当前单元测试的特点以及个人的经验。总之,请谨记在脑袋的是,一个测试是可以同时混合使用这两种期望的,因此我们可以灵活的使用它们。

  • Strict and non-strict mocks 严格和非严格mock

通常来说,我们最好站在一个独立的期望角度来思考使用严格性,而不是在一个mock实例或者类型上面考虑。等价的说法是,对于一个给定的mock实 例(或者类型)要么是严格的要么是非严格的。这意味着,特定实例/类型相关联的所有期望有相同的严格性。另一方面,在相同的测试,同时记录相同的mock 实例或类型的严格和非严格的期望,是完全有效的。而当使用在测试类级别声明的mock字段时,一个给定的mock实例在一个测试用例中是完全严格的,而同 时,在同一个测试类中,在另一个测试用例中,却是不严格的,这种情况是可以存在的。

总结下,我们可以指定三种不同严格性的方式:1)在一个给定的严格期望块中,如果需要指定某一个期望是非严格的,可以调用notStrict()方 法。2)对于一个特殊的mock类型/实例,其所有期望都需要是完全非严格的,则可以通过注解@NonStrict将其声明为一个mock属性字段或者参 数。3)如果在一个期望块中,需要所有的期望都是非严格的,则可以使用NonStrictExpectations类。

另一方面,这里没有提供任何一种方式去显式的指定某个给定的期望、mock类型/实例、或者一个完整的期望块应该是严格的。当我们没有指定期望是非 严格时,被记录下来的期望都被缺省认为是严格的。因此,对于一个期望需要被声明为严格时,它应该被记录在不在NonStrictExpectations 的期望expectation中,而对于mock类型,则不应该被注解为 @NonStrict. 而关联的mock类型和它相对应的所有实例都会被作为一个整体进行严格的校验,除了哪些匹配到一个被显式标记为非严格的调用。

最后,请注意,如果对于一个给定的Mock类型,在测试代码中没有任何相应的期望被记录,那么这个mock类型会自动被认为是一个完全不严格的(就好像这个mock的字段/参数被注解为 @NonStrict).

  • Iterated expectations 迭代期望
    当一系列有序连续的调用被记录在一个严格期望块中(调用之间的相对顺序与非严格的期望是无关的),整个序列则被期望在重播阶段执行。然而,让我们考虑下这 种情况,这些调用是在测试代码中的一个循环(或者任何其他迭代方式)里面执行。假设在测试代码中,我们是可以预先知道迭代次数,那么我们仍然记录这些期 望,匹配这些将在循环中执行的方法/构造函数(注意,我们并不是在一个期望代码块中,通过循环的方式声明调用期望)。通过使用 Expectations(int numberOfIterations)构造函数,下面的demo显示了这种特性。
    @Test
       public void recordStrictInvocationsInIteratingBlock(final Collaborator mock)
       {
          new Expectations(2) {{
             mock.setSomething(anyInt);
             mock.save();
          }};
     
          // In the tested code:
          mock.setSomething(123);
          mock.save();
          mock.setSomething(45);
          mock.save();
       }
     

这种指定一组调用的迭代次数的方式也适用于非严格期望。然而,非严格期望的情况下,迭代次数只是用于指定调用次数的上限和下限限制约束(包括隐式和显式的)。所以,对于非严格期望来说,没有指定调用次数约束,是没有影响的。

  • Explicit verification 显式验证(校验)
    严格期望是隐式校验的,所以,不需要在一个显式的校验块重复校验。另一方面,非严格期望通常在一个校验结构块中通过显式的方式来校验mock类型的调用。就如不久将看到的一样,一个被录制下来的非严格期望仍然可以通过隐式方式来校验,而不需要在校验块中编码调用校验。

在new Verifications() {...}块中,我们可以使用和NonStrictExpectations() {...}同样的方法或者字段API,用于指定期望返回值以及异常错误。也就说,我们可以自由的使用anyXyz字段、 withXyz(...)方法来匹配方法参数,以及使用times、minTimes和maxTimes来指定调用次数的约束。请看下面的例子。

@Test
   public void verifyInvocationsExplicitlyAtEndOfTest(final Dependency mock)
   {
      // Nothing recorded here, but it could be.
 
      // Inside tested code:
      Dependency dependency = new Dependency();
      dependency.doSomething(123, true, "abc-xyz");
 
      // Verifies that Dependency#doSomething(int, boolean, String) was called at least once,
      // with arguments that obey the specified constraints:
      new Verifications() {{ mock.doSomething(anyInt, true, withPrefix("abc")); }};
 

 

注意,默认情况下,一个verification校验会检查是否在重播阶段至少存在一个调用匹配到该校验。当我们需要指定调用的准确次数(包括1),那么就需要指定times=n这个约束。

  • Importing mocks from expectation blocks 从期望块中导入mock类型/实例

被声明在测试类属性字段域内的mock实例/类型,或者被声明在测试方法参数中的mock实例/类型,都是在校验块中使用。但是,我们知道,在 expectation块中同样可以声明一个局部的mock字段,这些字段是不可以被该块的外部使用。在这种情况下,我们可以参照下面的例子,将这些 mock实例导入到verification块中。

@Test
   public void importLocalMockFromPreviousNonStrictExpectationsBlock()
   {
      new NonStrictExpectations() {
         Dependency mock;
 
         {
            mock.notifyBeforeSave(); result = true;
         }
      };
 
      // Inside tested code:
      Dependency dependency = new Dependency();
      dependency.editABunchMoreStuff();
 
      new Verifications() {
         Dependency mock;
 
         {
            mock.editABunchMoreStuff();
         }
      };
   }
 

 

这些被导入的mock类型是通过在verification中声明的字段域类型来标示的,而不是字段名称,尽管通常情况下,相同的字段名称可以用来避免冲突。当不需要mock参数时,或者在内部创建一个mock实例时,这种特性是很有用的(后面部分再作解释)。

  • Verifying that an invocation never happened 判定一个调用从未执行
    为此,可以在verification块内部,在一个不需要在重播阶段执行的调用期望语句后面,添加times = 0语句。如果存在一个或者多个匹配该声明的调用发生,则会造成测试用例失败。
  • Verification in order 校验顺序
    一般的verification块(就好像上面的那个),是无序的。实际就是说,对于aMethod()和 anotherMethod()方法在重播阶段的执行顺序是不要求校验的,只是,需要保证在重播阶段至少执行一次就行。如果你需要校验调用之间的执行顺 序,那么就可以使用new VerificationsInOrder() {...}来替代。 在这个代码块中,只需要简单的按照mock类型被执行的顺序编写就行了。
    @Test
       public void verifyingExpectationsInOrder(final DependencyAbc abc)
       {
          // Somewhere inside the tested code:
          abc.aMethod();
          abc.doSomething("blah", 123);
          abc.anotherMethod(5);
          ...
     
          new VerificationsInOrder() {{
             // The order of these invocations must be the same as the order
             // of occurrence during replay of the matching invocations.
             abc.aMethod();
             abc.anotherMethod(anyInt);
          }};
       }
     

注意到,abc.doSomething(...)方法是不需要校验的,所以,它可以在任何时间点被执行(或者根本就没执行)。

  • Partially ordered verification 部分有序的校验
    假设,你需要判定一个特殊的方法(构造函数)在其他调用之前/之后被执行,但是你又不关心其他调用的顺序,那么就可以简单的在合适的地方调用unverifiedInvocations()方法就可以到达这个目的了。下面demo显示了该用法。
    @Mocked DependencyAbc abc;
       @Mocked AnotherDependency xyz;
     
       @Test
       public void verifyingTheOrderOfSomeExpectationsRelativeToAllOthers()
       {
          new UnitUnderTest().doSomething();
     
          new VerificationsInOrder() {{
             abc.methodThatNeedsToExecuteFirst();
             unverifiedInvocations(); // Invocations not verified must come here...
             xyz.method1();
             abc.method2();
             unverifiedInvocations(); // ... and/or here.
             xyz.methodThatNeedsToExecuteLast();
          }};
       }
     

    上面的例子实际上有点复杂了,因为它校验挺多东西的:a)一个方法必须要在其他方法之前被调用执行;b)一个方法必须在其他方法之后被执 行;c)AnotherDependency#method1()必须在DependencyAbc#method2()执行之后被调用。在大多数的测试 代码中,我们只需要保证这几种不同顺序的一个调用顺序就可以了。但是,强大的地方就在于这里,我们可以很容易的使用多种复杂顺序校验。

另一种情景没有被上面例子覆盖到的是,我们需要判定一些调用按照给定的顺序执行,同时需要另一些调用按照任意顺序执行。对此,我们需要编写两个独立的verification校验块,就好像上面示例一样(这里的mock是一个测试类的mock属性字段)

@Test
   public void verifyFirstAndLastCallsWithOthersInBetweenInAnyOrder()
   {
      // Invocations that occur while exercising the code under test:
      mock.prepare();
      mock.setSomethingElse("anotherValue");
      mock.setSomething(123);
      mock.notifyBeforeSave();
      mock.save();
 
      new VerificationsInOrder() {{
         mock.prepare(); // first expected call
         unverifiedInvocations(); // others at this point
         mock.notifyBeforeSave(); // just before last
         mock.save(); times = 1; // last expected call
      }};
 
      // Unordered verification of the invocations previously left unverified.
      // Could be ordered, but then it would be simpler to just include these invocations
      // in the previous block, in the place of the "unverifiedInvocations()".
      new Verifications() {{
         mock.setSomething(123);
         mock.setSomethingElse(anyString);
      }};
   }
 

 

通常情况下,当在测试代码中存在多个verification校验块时,它们的执行顺序就很重要。
In the previous test, for example, if the unordered block came before it would have left no "unverified invocations" to match a later call to unverifiedInvocations(); the test would still pass (assuming it originally passed) since it's not required that unverified invocations actually occurred at the called position, but it would not have verified that the unordered group of invocations occurred between the first and last expected calls.

  • Full verification 完整校验
    有时候,对mock类型所有的调用进行校验可能是很重要的。这自然就是记录严格期望时的情况,因为任何一个不希望发生的调用被执行都会造成测试失败。当在 非严格期望中使用显式的校验时,可以使用new FullVerifications() {...}块来确保没有调用未被校验。
    @Test
       public void verifyAllInvocations(final Dependency mock)
       {
          // Code under test included here for easy reference:
          mock.setSomething(123);
          mock.setSomethingElse("anotherValue");
          mock.setSomething(45);
          mock.save();
     
          new FullVerifications()
          {{
             // Verifications here are unordered, so the following invocations could be in any order.
             mock.setSomething(anyInt); // verifies two actual invocations
             mock.setSomethingElse(anyString);
             mock.save(); // if this verification (or any other above) is removed the test will fail
          }};
       }
     

    注意:如果一个下限约束(一个最小调用次数约束)被指定(除非是非严格期望),那么这个约束总会在测试代码最后结束前被隐式校验。因此,在全部验证块中显式的校验严格期望是没有必要的。

  • Full verification in order有序的完整校验
    目前,我们已经知道怎样使用Verifications处理无序的校验,如何使用VerificationsInOrder处理有序的校验,以及使用FullVerifications进行完整校验。但是,又如何处理有序的完整校验呢?足够的简单,如下:
    @Test
       public void verifyAllInvocationsInOrder(final Dependency mock)
       {
          // Code under test included here for easy reference:
          mock.setSomething(123);
          mock.setSomethingElse("anotherValue");
          mock.setSomething(45);
          mock.save();
     
          new FullVerificationsInOrder()
          {{
             mock.setSomething(anyInt);
             mock.setSomethingElse(anyString);
             mock.setSomething(anyInt);
             mock.save();
          }};
       }
     

    注意到,这里并没有什么不同的语法。在上面例子的verifyAllInvocations测试中,我们可以使用单一的verification校 验调用匹配两个独立mock.setSomething(...)方法。但是,在verifyAllInvocationsInOrder测试代码中,我 们在校验块中写了两个独立的调用,用来正确匹配。

现在,你可以会想,编写一个FullVerificationsInOrder其实就和编写一个Expectations块是一样的,因为 Expectations块中的所有期望都是严格的。那么我们是不是在重复造轮?并不完全是的。对于一个非严格的期望,缺省的被加上调用次数 minTimes = 1的约束,从而允许同一个方法或者构造函数在重播阶段可以多次执行。所以,在上面的例子中,如果setSomethingElse(...)方法在重播阶 段被连续二次调用执行,测试用例依然是可以通过的(前提是,第二次的调用需要按照期望顺序执行)。

  • Restricting the set of mocked types to be fully verified (完全校验某些mock类型的特定集合)

默认情况下,对于给定的测试,当使用 new FullVerifications() {}或者new FullVerificationsInOrder() {} 结构块时,所有mock实例/类型的所有调用都必须显式校验。现在,如果我们有一个测试,它有两个(或者更多)mock类型,但是我们只需要对这些 mock类型中的某一个(如果是多于2个mock类型,则可能是一个mock子集)做完整的调用校验,该怎么办?答案就是,使用 FullVerifications(Object... mockedTypesAndInstancesToVerify)构造函数,它只对这些给出的mock类型实例进行完整校验。下面的测试代码提供这样的 例子。

@Test
   public void verifyAllInvocationsToOnlyOneOfTwoMockedTypes(Dependency mock1, AnotherDependency mock2)
   {
      // Inside code under test:
      mock1.prepare();
      mock1.setSomething(123);
      mock2.doSomething();
      mock1.editABunchMoreStuff();
      mock1.save();
 
      new FullVerifications(mock1)
      {{
         mock1.prepare();
         mock1.setSomething(anyInt);
         mock1.editABunchMoreStuff();
         mock1.save(); times = 1;
      }};
   }
 

 

在上面的测试中,mock2.doSomething()调用是不会被验证的。如果需要只是针对某个class的方法(也包括构造函数)需要校验, 这也是可能的,只是需要将class传递给FullVerifications(...)或者 FullVerificationsInOrder(...) 构造函数里面。例如,new FullVerificationsInOrder(AnotherDependency.class) { ... }这个验证块仅仅保证所有AnotherDependency class的mock类型才被校验。

  • Verifying that no invocations occurred 验证没有任何调用被执行

为了在测试代码中验证非严格的mock类型/实例上的所有调用都没有执行,只需要添加一个空的完整校验块就行。一如往常,请注意,一个具有 times/minTimes调用次数约束的已记录的任何期望都会被隐式验证,因此不需要完整校验块;在这种情况下空校验块会确保没有其他调用发生。此 外,在同一个测试用例中,如果一个期望被之前的一个verification校验块验证过,则它同样不会被完整校验块所验证。

如果测试中使用了两个或者多个mock类型/实例,而你又需要校验某些Mock是没有任何调用发生的,那么就需要在一个空的校验块中指定需要校验的mock类型或者实例。正如下面例子所示:

@Test
   public void verifyNoInvocationsOnOneOfTwoMockedDependenciesBeyondThoseRecordedAsExpected(
      final Dependency mock1, final AnotherDependency mock2)
   {
      new NonStrictExpectations()
      {{
         // These two are recorded as expected:
         mock1.setSomething(anyInt); minTimes = 1;
         mock2.doSomething(); times = 1;
      }};
 
      // Inside code under test:
      mock1.prepare();
      mock1.setSomething(1);
      mock1.setSomething(2);
      mock1.save();
      mock2.doSomething();
 
      // Will verify that no invocations other than to "doSomething()" occurred on mock2:
      new FullVerifications(mock2) {};
   }
 

 

  • Verifying unspecified invocations that should not happen 验证未指定的不应该发生的调用
    一个完全校验块(无论是否有序)同样可以让我们来验证,某特定的方法和/或构造函数永远不会被调用,而无需为每一个方法/构造函数指定 times= 0。下面的测试提供了一个例子。
    @Test
       public void readOnlyOperation(final Dependency mock)
       {
          new NonStrictExpectations()
          {{
             mock.getData(); result = "test data";
          }};
     
          // Code under test:
          String data = mock.getData();
          // mock.save() should not be called here
          ...
     
          new FullVerifications()
          {{
             mock.getData(); minTimes = 0; // calls to getData are allowed
          }};
       }
     

如果在重播阶段,Dependency类的任何方法或者构造函数被调用,那么上面的测试将会失败,除非那些在校验块中显式的被校验 (Dependency#getData()就是这样)。另一方面,对于这种情况,我们根本不需要使用任何的验证块,而是更简单的使用一个严格期望就行 了。

  • Verifying iterations 验证迭代
    关于验证块,我们还有最后一种情况需要测试下:能够方便地验证发生在循环中的调用的循环迭代次数。
    @Test
       public void verifyAllInvocations(final Dependency mock)
       {
          int numberOfIterations = 3;
     
          // Code under test included here for easy reference:
          for (int i = 0; i < numberOfIterations; i++) {
             DataItem data = getData(i);
             mock.setData(data);
             mock.save();
          }
     
          new Verifications(numberOfIterations)
          {{
             mock.setData((DataItem) withNotNull());
             mock.save();
          }};
     
          new VerificationsInOrder(numberOfIterations)
          {{
             mock.setData((DataItem) withNotNull());
             mock.save();
          }};
       }
     

上面使用两个verification验证块目的是用来解释有序和无序的迭代验证的区别。在第一个验证块中,每一个验证调用都必须至少重播阶段中相 同方法3次,因为迭代次数被传递到构造函数里。对于无序的迭代块,指定迭代次数会用来乘以下限和上限的调用次数,当在验证块内指定一个明确的约束,如一个 minTimes= 1; maxTimes= 4,就会被乘以迭代次数;在上面的例子中就相当于被各自被乘以3,转化成minTimes= 3; maxTimes= 12;.另一方面,在第二个验证块中,调用次数的约束则无效。相反,产生的效果相当于"展开循环",就好像验证块校验调用的重复每个迭代。

迭代的FullVerifications块的语义和正常的校验块是一样的。迭代FullVerificationsInOrder块和一个VerificationsInOrder块也是一样。

分享到:
评论
1 楼 mill2008 2013-01-21  
翻译的很好,看了会英文的,实在有点晕,还是看这个比较快。不过貌似Behavior-based testing with JMockit这篇没结束呀,楼主还有新的吗?

相关推荐

    jdk1.8中文,java API谷歌翻译后校对版本

    java平台的API规范,标准版翻译校对版本,这是好心人翻译的,我认为目前是最好的中文api,分享下信息,chm版本

    JaamSim用户手册(翻译校对版).docx

    用户手册介绍了基本的用户界面和JaamSim提供的基本实体。这些特征对于这个软件创建的所有仿真模型来说都是常见的。还包括一些特定应用程序的文档说明,比如Ausenco运输物流模拟器(TLS)对应的相应的模块就能在手册中...

    《校对能手》中文文本校对软件

    《校对能手》是一款中文文稿校对软件。可以快速对中文文档资料进行校对,检查出可能存在的差错,列出勘误表,供改稿时参考。同时,还有姓名筛查、人名地名索引自动编排、多能字词典、中文排序等功能。特别适用于快速...

    《编辑助手》中文校对软件

    《编辑助手》又名“校对能手”是一款中文文稿校对软件。在各种文稿的起草、修改、抄写、打字、排版过程中,难免出现各种差错,手工校对检查费时费力,往往还会有所遗漏。本软件针对上述问题,可以快速对中文文档资料...

    黑马校对软件百度网盘下载地址

    黑马校对软件百度网盘下载地址,精确校对领导人姓名、职务和领导人排序错误。 精确校对涉及台湾和其他敏感的政治性错误。 即时更新的、可自定义的领导人职务库。校对插件 直接嵌入在Acrobat中校对PDF文件。可把校对...

    MISRA C 2012规范-中文精校版

    MISRA C 2012规范—中文精校版,精确翻译,校对。 220页内容,精心准备,望好评! MISRA C 2012规范—中文精校版,精确翻译,校对。 220页内容,精心准备,望好评! MISRA C 2012规范—中文精校版,精确翻译,校对。...

    自动控制原理实验指南(已校对)排版

    自动控制原理实验指南(已校对)排版 实验注意事项 (一)“综合实验台” 及其挂箱初次使用或较长时间未用时,实验前务必对“实验台”及其挂箱进行全面检查和单元环节调试。 (二)实验前,务必设置系统工作状态,并按...

    Spring官方文档(中文翻译&人工校对)

    满足markdown格式的Spring官方文档中文翻译版,一手信息才能掌握Spring!

    1Checker(易改英文校对软件)官方中文版V2.0.1.5 | 易改单词检查软件下载

    更有解释、翻译、词典以及英文写作辅助等实用功能来辅助用户快速改正错误,能极大地提高用户写作准确率的成文质量,是非常理想的英文写作和校对助手以及单词检查软件,除此之外易改还提供1Checker Word插件,支持MS ...

    \Winwps2000带校对(校对校对动态连接库)

    因文件上传不能超50M,因此再继续上传3个校对库文件。将3个校对库内的文件全部复制到\Winwps2000带校对压缩包你即可使用!

    中文自动校对

    我的专业工作案例可以从以下链接下载: ...需要预先安装同一目录下...中英文文本自动摘要、自动校对、自动分类、相关性与相似性聚类、主题词与标签自动生成、微博(短文本)聚类和情感分析。我的研究成果,欢迎下载传播。

    基于深度学习的中文文本自动校对研究与实现.pdf

    基于深度学习的中文文本自动校对研究与实现.pdf

    Finding All the Red M_翻译_校对_修改2次1

    找出所有的红色巧克力豆: 关于索引查询和全表扫描翻译人:姚稼接 校对人,lvan.Yu 原文地址:https://use-the-index-luke.com/

    Word语音打字校对专家 5.92 特别版

    Word语音打字校对专家是一款针对Word文档语音输入识别和语音合成软件,能在你键盘输入的同时把你在Word中所输入的字符或汉字读出来,这样就可以大幅度提高工作效率了,这点对于用五笔或其它形码的朋友来说就更显得...

    论文研究-基于中文分词的文本自动校对 .pdf

    基于中文分词的文本自动校对,颜军,潘昊,中文文本自动校对是自然语言处理领域中有着广阔应用前景的一个研究方向。本文依据中文分词的结果以及常见错误的特点,结合三元字

    梁截面校对_梁截面校对_梁截面_cad_截面校对vlx_

    该插件能实现cad模板图与模型之间的差异对比,更好的实现精确度

    即时语音提示&校对软件 InsTalk

    选中第三方输入法,它就可以在使用用户自己安装的任何一种汉字输入法时,汉字上屏以后读出语音提示。 声音 用来设置有关声音的各种功能。在语音库中选择男声或女声(以后的升级版本提供此项选择,本版本只有男声一...

    ITIL 4 foundation中文-4月校对.pdf

    本人翻译的ITIL 4 FOUNDATION文档

    29244-用户面控制面交互PFCP协议中英文对照--深入学习并校对了翻译增加了标注理解

    1. 29244-g00,为2019年6月份3GPP提交的标准文档。...2. 文档为本人下载网络上提供,后续因工作需要进行深入学习,里面的翻译已校对(实话前人提供的版本,就是一个google翻译的结果),并做了理解标注。

    逆向工程权威指南

    本书目前只有翻译87章,尚在更新,需完整版可以去看看十积分的这个 http://download.csdn.net/download/qq_39419087/9977947 2014年3月,编辑和Dennis签订中文版授权出版协议 2014年6月,Archer经过认真的考虑,...

Global site tag (gtag.js) - Google Analytics