Maven JBehave: codificando historias UTF8

Logramos crear y ejecutar pruebas con historias internacionalizadas usando JBehave dentro de eclipse. Todo salió bien.

Pero cuando tratamos de ejecutarlos usando el complemento maven, no podemos resolver el problema de codificación (por ejemplo, en lugar de leer "escenario" de la historia, aparece "Escenario": claramente un problema de codificación UTF8) .

¿Alguien ha encontrado una manera de hacer que JBehave lea las historias en UTF8 usando el complemento maven?

Lo que ya probamos:

  • agregando la opción -Dfile.encoding=UTF-8
  • cambiar el archivo de palabras clave usando UTF8
  • cambiando toda la codificación del proyecto en ISO => que funciona pero no es adecuado para la parte de producción que necesita mostrar mensajes en UTF8

nuestro Pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...

<properties>
    <jbehave.version>3.6.5</jbehave.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <resource.encoding>UTF-8</resource.encoding>
</properties>

<build>

    <testOutputDirectory>target/classes</testOutputDirectory>
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
        <testResource>
            <directory>src/test/story</directory>
        </testResource>
    </testResources>
    <plugins>
        ...
        <plugin>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.8</version>
            <configuration>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
                <additionalBuildcommands>
                    <buildcommand>com.google.gdt.eclipse.core.webAppProjectValidator</buildcommand>
                </additionalBuildcommands>
                <additionalProjectnatures>
                    <projectnature>com.google.gwt.eclipse.core.gwtNature</projectnature>
                </additionalProjectnatures>
                <classpathContainers>
                    <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
                </classpathContainers>
                <additionalConfig>
                    <file>
                        <name>.settings/org.eclipse.core.resources.prefs</name>
                        <content>
                           <![CDATA[eclipse.preferences.version=1
                           encoding/<project>=UTF-8]]>
                        </content>
                    </file>
                </additionalConfig>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.jbehave</groupId>
            <artifactId>jbehave-maven-plugin</artifactId>
            <version>${jbehave.version}</version>
            <executions>
                <execution>
                    <id>run-stories-as-embeddables</id>
                    <phase>test</phase>
                    <configuration>
                        <scope>test</scope>
                        <includes>
                            <include>**/*Story.java</include>
                        </includes>
                        <ignoreFailureInStories>true</ignoreFailureInStories>
                        <ignoreFailureInView>false</ignoreFailureInView>
                    </configuration>
                    <goals>
                        <goal>run-stories-as-embeddables</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-jbehave-site-resources</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <overwriteReleases>false</overwriteReleases>
                        <overwriteSnapshots>true</overwriteSnapshots>
                        <artifactItems>
                            <artifactItem>
                                <groupId>org.jbehave.site</groupId>
                                <artifactId>jbehave-site-resources</artifactId>
                                <version>3.1.1</version>
                                <type>zip</type>
                                <outputDirectory>
                                    ${project.build.directory}/jbehave/view
                                </outputDirectory>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
                <execution>
                    <id>unpack-jbehave-reports-resources</id>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <overwriteReleases>false</overwriteReleases>
                        <overwriteSnapshots>true</overwriteSnapshots>
                        <artifactItems>
                            <artifactItem>
                                <groupId>org.jbehave</groupId>
                                <artifactId>jbehave-core</artifactId>
                                <version>${jbehave.version}</version>
                                <outputDirectory>
                                    ${project.build.directory}/jbehave/view
                                </outputDirectory>
                                <includes>
                                    **\/*.css,**\/*.ftl,**\/*.js
                                </includes>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<dependencies>
    ...

    <!-- JBehave Dependencies -->
    <dependency>
        <groupId>org.jbehave</groupId>
        <artifactId>jbehave-core</artifactId>
        <version>${jbehave.version}</version>
    </dependency>

    <!-- Test Frameworks Dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-all</artifactId>
        <version>1.8.4</version>
        <scope>test</scope>
    </dependency>
</dependencies>

preguntado el 03 de mayo de 12 a las 11:05

4 Respuestas

He tenido cierto éxito subclasificando la clase org.jbehave.core.io.LoadFromClasspath, que uso en mi configuración como cargador de historias, es decir

MostUsefulConfiguration().useStoryLoader(new LoadFromClasspathUtf8());

aquí está mi subclase con la anulación del método adecuado:

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.jbehave.core.io.InvalidStoryResource;
import org.jbehave.core.io.LoadFromClasspath;

public class LoadFromClasspathUtf8 extends LoadFromClasspath {

    public LoadFromClasspathUtf8(Class<?> loadFromClass) {
        super(loadFromClass);
    }

    public LoadFromClasspathUtf8(ClassLoader classLoader) {
        super(classLoader);
    }

    @Override
    public String loadResourceAsText(String resourcePath) {
        InputStream stream = resourceAsStream(resourcePath);
        try {
            return IOUtils.toString(stream, "UTF-8");
        } catch (IOException e) {
            throw new InvalidStoryResource(resourcePath, stream, e);
        }
    }
}

Digo "Tuve cierto éxito" porque cuando miro los registros de mi ejecución de jbehave, los caracteres franceses acentuados como è,à,é, etc. se reemplazan por ?, pero luego, jbehave aún coincide con esto correctamente con los pasos que usan el RegexStoryParser. No me tomé el tiempo de investigar por qué sucede esto, pero estoy satisfecho de que mis historias funcionan correctamente ahora.

También agregué la propiedad del sistema file.encoding a la configuración de mi complemento para dejar en claro que tengo la intención de usar la codificación UTF-8.

respondido 14 nov., 12:16

¡Gracias, esto también me ayudó a ejecutar las pruebas correctamente en eclipse! - Santosh

El mismo problema aquí también. Incluso después de agregar el parámetro "-Dfile.encoding=UTF-8" a MAVEN_OPTS, el problema persistió. Resulta que tenía esta línea dentro de mi archivo ~/.mavenrc:

export MAVEN_OPTS="-Xmx1024m"

Lo que estaba sucediendo es que la variable MAVEN_OPTS se restableció antes de ejecutar la JVM.

Después de cambiar el archivo ~/.mavenrc a:

export MAVEN_OPTS="$MAVEN_OPTS -Xmx1024m"

El problema fue resuelto. La codificación del archivo se establece correctamente cuando se ejecuta:

export MAVEN_OPTS="$MAVEN_OPTS -Dfile.encoding=UTF-8"
mvn clean integration-test

Respondido el 12 de junio de 12 a las 17:06

Dado que tiene sus historias en el contexto de "prueba" en lugar de "principal" (en otro módulo), creo que probablemente esté sucediendo algo cuando las historias se copian en clases objetivo/de prueba.

contestado el 09 de mayo de 12 a las 22:05

Pensé en eso, es por eso que especifiqué en el POM: objetivo/clases y revisé, las clases están ahí - Antoine

Entonces, ¿sus historias están UTF-8 en ese directorio? - Brian Reko

Tuve exactamente el mismo problema. De forma predeterminada, JBehave no respeta la codificación de la plataforma. Para solucionar esto, puede usar este StoryLoader personalizado que respeta la propiedad del sistema file.encoding:

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.commons.io.IOUtils;
import org.jbehave.core.io.InvalidStoryResource;
import org.jbehave.core.io.LoadFromClasspath;

/**
 * @author cedric.vidal
 *
 */
public class FixedStoryLoader extends LoadFromClasspath {

    public String loadResourceAsText(String resourcePath) {
        InputStream stream = resourceAsStream(resourcePath);
        try {
            return IOUtils.toString(stream, platformCharset().name());
        } catch (IOException e) {
            throw new InvalidStoryResource(resourcePath, stream, e);
        }
    }

    public static Charset platformCharset() {
        String csn = System.getProperty("file.encoding");
        Charset cs = Charset.forName(csn);
        if (cs == null) {
            cs = Charset.forName("UTF-8");
        }
        return cs;
    }

}

Regístrelo en la configuración de JBehave con:

new MostUsefulConfiguration().useStoryLoader(new FixedStoryLoader());

Configure su POM para usar UTF-8 en todos los complementos correspondientes (m2eclipse también lo usará):

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

Y dígale al JBehave Maven Plugin que lo use también (busque el bloque systemProperties):

        <plugin>
            <groupId>org.jbehave</groupId>
            <artifactId>jbehave-maven-plugin</artifactId>
            <version>${jbehave.core.version}</version>
            <executions>
                <execution>
                    <id>unpack-view-resources</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>unpack-view-resources</goal>
                    </goals>
                </execution>
                <execution>
                    <id>embeddable-stories</id>
                    <phase>integration-test</phase>
                    <configuration>
                        <includes>
                            <include>${embeddables}</include>
                        </includes>
                        <excludes/>
                        <systemProperties>
                            <property>
                                <name>file.encoding</name>
                                <value>${project.build.sourceEncoding}</value>
                            </property>
                        </systemProperties>
                        <ignoreFailureInStories>true</ignoreFailureInStories>
                        <ignoreFailureInView>false</ignoreFailureInView>
                        <threads>1</threads>
                        <metaFilters>
                            <metaFilter/>
                        </metaFilters>
                    </configuration>
                    <goals>
                        <goal>run-stories-as-embeddables</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

contestado el 16 de mayo de 12 a las 19:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.