Selenium Java中ImageIO.read(URL)无法读取图片致Logo对比失败求助
问题:ImageIO读取Magento站点Logo URL返回null导致图片对比失败
使用Selenium WebDriver Java结合Cucumber做自动化测试,验证Magento Luma站点Logo一致性:计划通过ImageIO读取Logo的URL存为预期图,再用AShot截取页面Logo元素作为实际图对比。但执行BufferedImage buffimg =ImageIO.read(new URL(webImageLoc))时返回null,控制台输出“image == null!”,最终断言失败。
PageObject代码
public class HomePage extends BasePage { public HomePage(WebDriver driver) { super(driver); } // Declaring global parameters WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10)); //Elements for page details @FindBy(xpath = "//a[@aria-label='store logo']//img") WebElement logoLuma; public boolean compareHomePageLogo() throws IOException { boolean results = false; WebElement imgLuma = wait.until(ExpectedConditions.elementToBeClickable(logoLuma)); // First downloading the logo image and storing it in local machine String webImageLoc = imgLuma.getAttribute("src"); //System.out.println("URL is: " + new URL(webImageLoc)); BufferedImage buffimg =ImageIO.read(new URL(webImageLoc)); System.out.println(buffimg); File outputFile = new File(System.getProperty("user.dir")+"\\Screenshots\\expected.png"); ImageIO.write(buffimg, "png", outputFile); // Taking screenshot of image element from search results Screenshot shot = new AShot().takeScreenshot(driver, imgLuma); File screenshotFile = new File(System.getProperty("user.dir") + "\\Screenshots\\actual.png"); ImageIO.write(shot.getImage(), "png", screenshotFile); // Comparing both images BufferedImage expectedImage = ImageIO.read(outputFile); // Getting expected image BufferedImage actualImage = shot.getImage(); // Getting actual image ImageDiffer imgDiff = new ImageDiffer(); ImageDiff diff = imgDiff.makeDiff(expectedImage, actualImage); // Storing diff result if(diff.hasDiff()) { System.out.println("Images are not same."); results = false; } else { System.out.println("Images are same."); results = true; } return results; } }
Step定义代码
@Then("user can see the LUMA image on page") public void user_can_see_the_luma_image_on_page() { hp = new HomePage(driver); try { Assert.assertTrue("Images are not same.", hp.compareHomePageLogo()); } catch(Exception e) { logger.info(e.getMessage()); Assert.fail(); } }
TestRunner代码
package testRunner; import io.cucumber.junit.Cucumber; import io.cucumber.junit.CucumberOptions; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions ( features = { ".//src/test/resources/Features/LandingPage.feature" }, glue = "stepDefinitions", plugin = { "pretty", "html:reports/myreport.html", "json:reports/myreport.json", "rerun:target/rerun.txt", // Mandatory to capture failures "html:target/cucumber-html-report", "json:target/cucumber-reports/cucumber.json", "junit:target/cucumber-reports/cucumber.xml", "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:" }, dryRun = false, monochrome = true, tags = "@temp" ) public class TestRunner { }
报错信息
Given user navigates to "https://magento.softwaretestingboard.com/" # stepDefinitions.HomePageSteps.user_navigates_to(java.lang.String) When user can see the "Default welcome msg!" on page # stepDefinitions.HomePageSteps.user_can_see_the_on_page(java.lang.String) **null** 15:01:19.989 [main] INFO stepDefinitions.HomePageSteps - **image == null!** Then user can see the LUMA image on page # stepDefinitions.HomePageSteps.user_can_see_the_luma_image_on_page() java.lang.AssertionError at org.junit.Assert.fail(Assert.java:87) at org.junit.Assert.fail(Assert.java:96) at stepDefinitions.HomePageSteps.user_can_see_the_luma_image_on_page(HomePageSteps.java:109) at ✽.user can see the LUMA image on page(file:///C:/Users/priyank.shah3/eclipse-workspace/Luma_eCommerce/./src/test/resources/Features/LandingPage.feature:17) Scenario status ======>FAILED
解决方案
1. 核心原因确认
Magento Luma站点的Logo是SVG格式,而Java原生的ImageIO默认不支持SVG格式的读取,这是返回null的直接原因。
2. 方案一:引入SVG转码库读取
添加Apache Batik依赖(用于SVG转PNG),将SVG转为BufferedImage:
- 先在pom.xml中添加依赖:
<dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-transcoder</artifactId> <version>1.17</version> </dependency>
- 修改原图片读取代码:
import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.PNGTranscoder; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; // 替换原ImageIO.read(new URL(webImageLoc))代码段 String webImageLoc = imgLuma.getAttribute("src"); URL svgUrl = new URL(webImageLoc); PNGTranscoder transcoder = new PNGTranscoder(); TranscoderInput input = new TranscoderInput(svgUrl.openStream()); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); TranscoderOutput output = new TranscoderOutput(outputStream); transcoder.transcode(input, output); // 将转码后的字节流转为BufferedImage BufferedImage buffimg = ImageIO.read(new ByteArrayInputStream(outputStream.toByteArray()));
3. 方案二:使用本地预存的预期图
如果不想引入额外依赖,可手动将SVG格式的Logo转为PNG,保存到项目本地目录,直接读取本地文件作为预期图:
// 替换原URL读取代码 BufferedImage buffimg = ImageIO.read(new File(System.getProperty("user.dir") + "\\src\\test\\resources\\expected_logo.png"));
4. 辅助排查:模拟浏览器请求头
部分站点会拦截无UA标识的请求,可给URL请求添加浏览器User-Agent:
URL url = new URL(webImageLoc); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); BufferedImage buffimg = ImageIO.read(connection.getInputStream());
内容的提问来源于stack exchange,提问作者Priyank Shah
相关产品推荐
相关产品推荐

